# Sofascore Live Scores & Fixtures Scraper (`incognito_mode/sofascore-live-scores-scraper`) Actor

Scrape Sofascore live scores and fixtures across 19 sports — football,
basketball, tennis, ice hockey, cricket and more. Get teams, scores, status,
kick-off time, tournament and country per match. No API key, no login, no
residential proxy — runs on the free plan. Export JSON, CSV or Excel.

- **URL**: https://apify.com/incognito\_mode/sofascore-live-scores-scraper.md
- **Developed by:** [Elena Vance](https://apify.com/incognito_mode) (community)
- **Categories:** News, Developer tools, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.50 / 1,000 matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Sofascore Live & Daily Scores Scraper

Scrape live scores and daily fixtures from Sofascore across **19 sports** --
football, basketball, tennis, ice hockey, cricket, volleyball, handball,
baseball, and more. No Sofascore API key, no login.

Results are stored in an Apify dataset you can export as **JSON, CSV, Excel,
XML or HTML**.

### What you get

A real run, `{ "sports": ["football"], "dateFrom": "2026-08-23" }`:

| Home | | | Away | Status | Competition | Kick-off (UTC) |
| --- | :-: | :-: | --- | --- | --- | --- |
| Newcastle United | 2 | 2 | Liverpool FC | finished | Premier League | 2026-08-23 15:30 |
| Manchester City | 2 | 1 | Bournemouth | finished | Premier League | 2026-08-23 13:00 |
| Brighton & Hove Albion | 4 | 0 | Aston Villa | finished | Premier League | 2026-08-23 13:00 |
| Athletic Club | 1 | 3 | Sevilla | finished | LaLiga | 2026-08-22 15:00 |

Every row also carries team IDs, tournament and unique-tournament IDs, the
country, a status code, a Unix timestamp, and a direct link to the match —
see [Output](#output) for the full shape.

***

### Why this is cheap to run

**No proxy required, and no premium plan required.**

This Actor talks to `sofascore.com/api/v1` **directly** — no headless
browser, and no proxy at all unless Sofascore actually blocks a request.
Sofascore screens requests on their TLS handshake, which this Actor clears
with a browser-grade HTTP client rather than by paying for egress.

If an IP does get blocked, the Actor escalates on its own, cheapest first:

1. **Direct** — free, and where most runs stay for their whole lifetime.
2. **Datacenter proxy** — included in *every* Apify plan, the free tier
   included. A few IPs are rotated here, which is usually enough.
3. **Residential proxy** — only if your plan has it, and only once the free
   tier above is exhausted.

So there is **no residential-proxy add-on requirement**, and a run that is
never blocked spends nothing on proxy at all. See
[`docs/architecture.md`](docs/architecture.md) for the measurements behind
this.

### Two modes

| Mode | Input | What it fetches |
| --- | --- | --- |
| **Live** (`liveOnly: true`) | none needed | Every match currently in progress, for each sport selected. One fast call per sport. |
| **Daily schedule** (default) | `dateFrom` / `dateTo` | Matches for each date in range. Discovers which tournaments played that day, ranks them by Sofascore's own follower count, and fetches the top `maxTournamentsPerDate` (default 30) -- or pass `tournamentIds` yourself to skip discovery and fetch exactly the competitions you want. |

### What makes this different

- **19 sports through one column set.** Tennis, cricket, volleyball, handball,
  baseball and the rest come back in the same shape as football, so one parser
  handles all of them.
- **Tournament discovery is ranked, not arbitrary.** In daily mode the Actor
  works out which competitions actually played that day and orders them by
  Sofascore's own follower count before fetching the top
  `maxTournamentsPerDate`. You get the matches people care about first rather
  than a random slice — or pass `tournamentIds` and skip discovery entirely.
- **A $0.00005 start fee**, against up to $0.08 on comparable Sofascore
  Actors. On a run that fetches a single date, that gap is most of the bill.
- **Failures are never billed.** Rows are charged only once stored; a
  tournament that cannot be read is reported in the run summary and costs
  nothing, and unusable input returns an unbilled diagnostic row instead of
  failing the run.
- **No API key, no login, no headless browser, no residential-proxy add-on** —
  see [Why this is cheap to run](#why-this-is-cheap-to-run).

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `sports` | array of strings | `["football"]` | One or more of the 19 supported sport slugs. |
| `liveOnly` | boolean | `false` | Fetch only in-progress matches instead of a daily schedule. |
| `dateFrom` | string (`YYYY-MM-DD`) | today (UTC) | First date to fetch. Ignored when `liveOnly` is on. |
| `dateTo` | string (`YYYY-MM-DD`) | `dateFrom` | Last date to fetch, inclusive. Max 31 days per run. Ignored when `liveOnly` is on. |
| `tournamentIds` | array of integers | – | Sofascore unique-tournament IDs (e.g. `17` = Premier League, `8` = LaLiga). Skips tournament discovery for a fully predictable request count. |
| `maxTournamentsPerDate` | integer | `30` | Cap on how many discovered tournaments to fetch per date, ranked by follower count. Only used when `tournamentIds` is empty. |
| `maxDiscoveryPages` | integer | `2` | How deep to page through tournament discovery. Page 1 already carries every major league, so the default keeps runs fast; raise it only to reach genuinely obscure competitions. |
| `maxItems` | integer | `500` | Hard cap on stored matches. The run stops as soon as it is reached. |
| `proxyConfiguration` | object | off | Leave off. Direct calls with automatic cheapest-first proxy escalation only if blocked. Set this only to pin a specific proxy — e.g. to scrape from a particular country. |

### Output

One dataset row per match:

```json
{
  "eventId": 12435678,
  "sport": "football",
  "tournament": {
    "name": "Premier League",
    "id": 1,
    "uniqueTournamentId": 17,
    "uniqueTournamentName": "Premier League"
  },
  "category": "England",
  "homeTeam": { "id": 17, "name": "Manchester City", "shortName": "Man City" },
  "awayTeam": { "id": 38, "name": "Chelsea", "shortName": "Chelsea" },
  "homeScore": 2,
  "awayScore": 1,
  "status": { "code": 100, "description": "Ended", "type": "finished" },
  "startTimestamp": 1786284000,
  "startTimeIso": "2026-08-23T14:00:00+00:00",
  "slug": "manchester-city-chelsea",
  "matchUrl": "https://www.sofascore.com/football/match/manchester-city-chelsea#id:12435678"
}
```

### Example: today's live football

```json
{ "sports": ["football"], "liveOnly": true }
```

### Example: this week's Premier League and LaLiga fixtures

```json
{
  "dateFrom": "2026-08-24",
  "dateTo": "2026-08-30",
  "tournamentIds": [17, 8]
}
```

***

### The Sofascore Actor suite

Six Actors from the same publisher, built on one shared HTTP layer and one ID
space — so the output of one is the input of the next.

| Actor | What it returns |
| --- | --- |
| **Live Scores & Fixtures** | *This Actor.* |
| [Match Stats, xG & Lineups](https://apify.com/incognito_mode/sofascore-match-analytics-scraper) | Per-match shotmaps with pitch coordinates, lineups, ratings, momentum. Takes `eventId`. |
| [League Standings & Tables](https://apify.com/incognito_mode/sofascore-standings-scraper) | League tables, group stages, conferences and divisions. Takes `uniqueTournamentId`. |
| [Team & Player Data](https://apify.com/incognito_mode/sofascore-team-player-scraper) | Squads, bios, market values, transfers, match logs. Takes team and player IDs. |
| [Season Stats](https://apify.com/incognito_mode/sofascore-season-stats-scraper) | Season leaderboards and complete team statistics. Takes `uniqueTournamentId`. |
| [Rankings & Search](https://apify.com/incognito_mode/sofascore-rankings-scraper) | FIFA, ATP/WTA, UEFA and UFC tables, plus name-to-ID search. |

**How they chain.** Live Scores emits the `eventId` that Match Stats takes.
Rankings' search turns a name into the team, player and tournament IDs the
other five accept. Standings and Season Stats share `uniqueTournamentId`, and
Team & Player emits that same ID as `primaryTournamentId`.

All six need no API key, no login and no headless browser; none requires a
residential-proxy add-on, and all run on the Apify free plan.

# Actor input Schema

## `sports` (type: `array`):

One or more sports to fetch. Each is queried separately.

## `liveOnly` (type: `boolean`):

Fetch only matches currently in progress (one fast call per sport, always "now" -- no date range needed). Turn off to fetch a daily schedule instead, using Date from / Date to below.

## `dateFrom` (type: `string`):

First date to fetch (YYYY-MM-DD). Defaults to today (UTC). Ignored when "Live matches only" is on.

## `dateTo` (type: `string`):

Last date to fetch (YYYY-MM-DD), inclusive. Defaults to "Date from". Max 31 days per run. Ignored when "Live matches only" is on.

## `tournamentIds` (type: `array`):

Sofascore unique-tournament IDs to fetch directly for the date range, e.g. \[17, 8] for Premier League and LaLiga (find IDs on a tournament's Sofascore page URL). Skips the tournament-discovery step entirely, so a run stays fast and predictable even for a wide date range. Ignored when "Live matches only" is on.

## `maxTournamentsPerDate` (type: `integer`):

When "Tournament IDs" is empty, how many tournaments (ranked by Sofascore follower count) to fetch matches for on each date. A single day of football alone can have 100+ tournaments with at least one match; this keeps a default run's request count predictable. Raise it for comprehensive coverage.

## `maxDiscoveryPages` (type: `integer`):

How deep to page through the tournament-discovery step on each date. Sofascore groups these pages roughly by importance: page 1 carries every major league (hundreds of thousands of followers) while later pages top out in the low tens of thousands, so paging to the very end costs extra requests to surface tournaments the ranking then discards. Raise it only if you also raise "Max tournaments per date" and want genuinely obscure competitions. Ignored when "Tournament IDs" is set.

## `maxItems` (type: `integer`):

Hard cap on how many matches are stored in the dataset. The run stops as soon as it is reached.

## `proxyConfiguration` (type: `object`):

Leave off. Every request calls Sofascore directly first, which costs nothing, and most runs never need anything else. If Sofascore does block an IP, the Actor escalates on its own: first to a datacenter proxy (included in every Apify plan, free tier included), rotating a few IPs, and only then to a residential one if your plan has them. No residential add-on is required. Set this only to pin a specific proxy configuration from the start -- for example to scrape from a particular country.

## Actor input object example

```json
{
  "sports": [
    "football"
  ],
  "liveOnly": false,
  "maxTournamentsPerDate": 30,
  "maxDiscoveryPages": 2,
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing every scraped match.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sports": [
        "football"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("incognito_mode/sofascore-live-scores-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "sports": ["football"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("incognito_mode/sofascore-live-scores-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sports": [
    "football"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call incognito_mode/sofascore-live-scores-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,incognito_mode/sofascore-live-scores-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ECZT9ET0F2KfWQPES/builds/oJv724VDvhW2dB7i1/openapi.json
