# SofaScore Scraper - Results, Stats, Lineups, Ratings & Odds (`artsiom_k/sofascore-scraper`) Actor

SofaScore data for football, basketball, hockey, tennis and 17 more sports: results with period scores, team stats (xG, possession, shots), lineups with player ratings, incidents and opening/closing odds. By day, team or tournament season back to the 1990s.

- **URL**: https://apify.com/artsiom_k/sofascore-scraper.md
- **Developed by:** [Artsiom Kunitsyn](https://apify.com/artsiom_k) (community)
- **Categories:** Other
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## SofaScore Scraper - Results, Stats, Lineups, Ratings & Odds

Match data from [SofaScore](https://www.sofascore.com) for **football (soccer), basketball, ice hockey, American
football, baseball, tennis, handball, volleyball, rugby, cricket, esports** and 10 more sports:

- **Matches**: final score, score per half / quarter / period / set, overtime and penalties, winner, tournament,
  season, round, teams. Optionally venue, attendance, referee and managers.
- **Match statistics**: every team statistic SofaScore shows (possession, expected goals, shots, big chances,
  passes, duels, tackles, corners, cards; shots, hits, power plays and giveaways in ice hockey),
  for the whole match and each period.
- **Lineups and player ratings**: every player in the squad with SofaScore's rating, minutes played, position, shirt
  number, market value and all per-player statistics (passes, duels, xG, xA, distance covered, saves ...).
- **Incidents**: goals with assists, cards, substitutions, VAR decisions, period ends and injury time.
- **Odds**: opening and closing odds for 1X2, double chance, totals, handicaps, both teams to score and more.

Pick matches **by day** (any day from 2026-01-01), **by tournament and season** (whole seasons back to the 1990s:
the Premier League from 1992/93), **by team**, or **by match URL**. Built for reliability: the Actor finds proxy IPs
that SofaScore lets through and keeps reusing them.

### What you get

`entityType: "events"` (the default) returns one row per match:

| Field | Example |
|---|---|
| `sport`, `event_id`, `date`, `start_time_utc` | `football`, `16938974`, `2026-10-14`, `2026-10-14T16:45+00:00` |
| `tournament`, `season`, `round`, `category` | `UEFA Champions League`, `26/27`, `2`, `Europe` |
| `home_team`, `away_team`, `home_score`, `away_score` | `Feyenoord`, `Como`, `3`, `2` |
| `winner`, `status`, `status_description` | `Feyenoord`, `finished`, `Ended` |
| `periods` | `[{"period": 1, "home": 1, "away": 1}, {"period": 2, "home": 2, "away": 1}]` |
| `home_score_overtime`, `home_score_penalties` | extra time and shoot-out scores when played |
| `venue`, `attendance`, `referee`, `home_manager` | with **Include venue, referee and attendance** |
| `event_url` | the SofaScore match page |

Every other type repeats the match columns (`date`, `tournament`, `home_team`, `away_team`, scores, `event_url`) and
adds:

- **`statistics`**: one row per match period (`period` = `match`, `1`, `2` ...). Each statistic is two columns,
  `home_<name>` and `away_<name>`, e.g. `home_ball_possession`, `away_expected_goals`, `home_total_shots_on_goal`,
  `home_corner_kicks`. Ratios add a `_total` column (`home_accurate_passes` of `home_accurate_passes_total`).
- **`lineups`**: one row per player: `side`, `team`, `formation`, `player`, `position`, `shirt_number`, `starter`,
  `captain`, `minutes_played`, `rating`, `market_value`, `player_country`, `player_date_of_birth` and
  `player_statistics` (an object with every per-player statistic).
- **`incidents`**: one row per incident in match order: `incident_type` (`goal`, `card`, `substitution`,
  `varDecision`, `period` ...), `incident_class` (`regular`, `penalty`, `ownGoal`, `yellow`, `red` ...), `minute`,
  `added_time`, `team`, `player`, `assist`, `player_in`, `player_out`, `home_score_after`, `away_score_after`.
- **`odds`**: one row per market selection: `market_group` (`1X2`, `Double chance`, `Match goals`, `Asian handicap`,
  `Both teams to score` ...), `market_period`, `line` (e.g. `2.5`), `selection`, `opening_odds`, `current_odds`
  (decimal; the closing odds once the match is over), the fractional odds and `winning`.

### How to use it

- **Yesterday's and today's football results** (the default): just run it.
- **Several sports**: pick them under **Sports**, e.g. basketball and ice hockey.
- **A whole season**: Tournaments = `https://www.sofascore.com/football/tournament/england/premier-league/17`,
  Seasons = `2024/2025`, clear **Max items**. Seasons = `all` for every season SofaScore has.
- **xG and shots for a league**: the same, with `entityType: "statistics"`.
- **Player ratings**: `entityType: "lineups"` for the matches you want.
- **A team's recent form**: Teams = the team's SofaScore URL, **From date** = how far back.
- **Pre-match odds and closing lines**: `entityType: "odds"`; **Match status** = upcoming for today's and tomorrow's
  fixtures, finished for closing odds.
- **A daily feed**: schedule it daily with the default dates, **Max items** cleared and **Mode** = incremental: each
  run returns only finished matches earlier runs didn't.

### Input

| Field | Default | What it does |
|---|---|---|
| `entityType` | `events` | `events`, `statistics`, `lineups`, `incidents` or `odds`. |
| `sports` | football | Listing by day: which sports. |
| `dateFrom`, `dateTo` | yesterday and today | Listing by day from 2026-01-01 on. With tournaments or teams, the dates only filter. |
| `eventStatus` | `finished` | `finished`, `upcoming` or `all`. |
| `tournaments`, `seasons` | none | Tournament URLs or ids, and which seasons (`2024/2025`, `24/25`, `2024`, `all`; empty = newest). |
| `teams` | none | Team URLs or ids: their matches across all competitions. |
| `eventIds` | none | Match URLs or ids. |
| `includeEventDetails` | off | Venue, attendance, referee and managers (one extra request per match). |
| `maxItems` | `50` | Row cap. Clear it for everything. |
| `mode` | `full` | `incremental` skips finished matches earlier incremental runs returned. |
| `concurrency` | `10` | Requests in parallel. |
| `proxyConfiguration` | Apify Proxy | SofaScore blocks most IPs; proxy traffic is included in the price. |

### Good to know

- Times and dates are UTC.
- Smaller leagues often have results only: statistics, lineups and odds exist mostly for the bigger competitions. A
  run lists the biggest competitions first, so a capped run gets the matches that have data.
- `home`/`away` follow SofaScore's order. In tennis they are player 1 and player 2.
- Odds come from SofaScore's default bookmaker and show opening and current odds, not every move in between.
- Listing by day starts at 2026-01-01; older seasons are reached through Tournaments or Teams.
- Standings are not included.

### Related sports data scrapers

- [Flashscore Scraper](https://apify.com/artsiom_k/flashscore-scraper) — results, statistics, lineups and opening/closing odds from ~20 bookmakers for 17 sports.
- [TennisExplorer Scraper](https://apify.com/artsiom_k/tennisexplorer-scraper) — ATP/WTA/ITF results to the 1990s, bookmaker odds and SofaScore serve/return statistics.
- [Action Network Scraper](https://apify.com/artsiom_k/actionnetwork-scraper) — US sportsbook odds, public betting splits, line movement, props, injuries and futures.
- [Sports Odds History Scraper](https://apify.com/artsiom_k/sports-odds-history-scraper) — opening and closing lines per sportsbook since 2021 and ATS results since 2006.
- [Smarkets Betting Exchange Scraper](https://apify.com/artsiom_k/smarkets-scraper) — betting exchange back and lay odds, matched volume, results and traded-price history.
- [Kalshi & Polymarket Scraper](https://apify.com/artsiom_k/prediction-markets-scraper) — prediction market odds, settled results and price history.

# Actor input Schema

## `entityType` (type: `string`):

One row per match, per match period (statistics), per player (lineups), per incident or per odds selection.

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

Listing by day: which sports. Ignored when Tournaments, Teams or Match URLs are given.

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

First day (YYYY-MM-DD, UTC). Leave both dates empty for yesterday and today (upcoming: today and tomorrow). Listing by day starts at 2026-01-01; for older matches use Tournaments or Teams, where the dates only filter.

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

Last day (YYYY-MM-DD, UTC).

## `eventStatus` (type: `string`):

Finished matches have results, statistics and closing odds; upcoming ones have fixtures and current odds.

## `tournaments` (type: `array`):

SofaScore tournament URLs or ids, e.g. https://www.sofascore.com/football/tournament/england/premier-league/17 or 17. Returns whole seasons (see Seasons), any year SofaScore has (the Premier League back to 1992/93).

## `seasons` (type: `array`):

Tournaments only: which seasons, e.g. 2024/2025, 24/25 or 2024 (calendar-year leagues). Empty = the newest season (or the one in the tournament URL's #id:). "all" = every season.

## `teams` (type: `array`):

SofaScore team URLs or ids, e.g. https://www.sofascore.com/football/team/manchester-united/35. Returns the team's matches across all competitions, newest first; use the dates to limit how far back.

## `eventIds` (type: `array`):

SofaScore match URLs (…#id:16938974) or match ids. Overrides every other way of picking matches.

## `includeEventDetails` (type: `boolean`):

Matches only: adds venue, city, capacity, attendance, referee and both managers (one extra request per match).

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

Stop after this many rows. Clear it for everything in range.

## `mode` (type: `string`):

"incremental" remembers the finished matches earlier incremental runs with the same settings returned and skips them, so a daily schedule gets only new results.

## `concurrency` (type: `integer`):

Requests in parallel.

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

SofaScore blocks most IPs. The Actor finds Apify Proxy (datacenter) IPs that get through and keeps reusing them. Proxy traffic is included in the price.

## Actor input object example

```json
{
  "entityType": "events",
  "sports": [
    "football"
  ],
  "eventStatus": "finished",
  "includeEventDetails": false,
  "maxItems": 50,
  "mode": "full",
  "concurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("artsiom_k/sofascore-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 = { "proxyConfiguration": { "useApifyProxy": True } }

# Run the Actor and wait for it to finish
run = client.actor("artsiom_k/sofascore-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 '{
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call artsiom_k/sofascore-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,artsiom_k/sofascore-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/6XYRRJafVIC3ZC4Ut/builds/orXBKkWy0uef0hZPG/openapi.json
