# Sofascore Match Stats Scraper - Live Scores, Odds & Lineups (`punkrecordsdata/sofascore-match-stats-scraper`) Actor

Scrape Sofascore match data across 11 sports: live scores, statistics, lineups, shot maps, player ratings, head-to-head and odds. Export to CSV, Excel, JSON.

- **URL**: https://apify.com/punkrecordsdata/sofascore-match-stats-scraper.md
- **Developed by:** [PunkRecordsData](https://apify.com/punkrecordsdata) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 match summaries

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?

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

<p align="center">
  <img src="https://api.apify.com/v2/key-value-stores/AAm3a1h3Z9nYfrvh9/records/banner" alt="PunkRecordsData" width="100%" />
</p>

## ⚽ Sofascore Match Stats Scraper: PunkRecordsData

> 🚀 **Export Sofascore match data in seconds.** 22 fields per match across
> 11 sports, with up to 7 optional data extras, statistics, lineups, shot
> maps, player ratings, head-to-head records and live odds, in a single run.

Scrape Sofascore match data straight from the site's own internal API: live
scores, full statistics, starting lineups, shot-by-shot maps with expected
goals (xG), per-player ratings, head-to-head history and bookmaker odds. Every
match comes back as one clean row, not a raw JSON dump. Pick a team by name
or a specific match ID and get real numbers back, verified against live
Sofascore data before this Actor shipped.

Covers **11 sports** (football, basketball, tennis, American football, ice
hockey, baseball, rugby, esports, volleyball, handball, table tennis), with
statistics broken into 40+ line items per football match (possession, shots,
expected goals, cards, sprints and more), full starting XI with formations,
and shot-by-shot maps with player, body part and xG for every attempt.

| 🎯 Target Audience | 💡 Primary Use Cases |
|---|---|
| Sports data analysts, fantasy sports tools, betting research platforms, sports media, LLM/agent pipelines | Live score feeds, post-match statistics dashboards, lineup and formation tracking, historical head-to-head research, odds comparison |

### 📋 What the Sofascore Match Stats Scraper does

Give it a team name (e.g. "Real Madrid") and it resolves the team, pulls its
recent and upcoming fixtures, and returns one row per match with the base
score, tournament and status. Turn on any of 7 optional extras and each one
adds its own real data to the same row: team statistics, starting lineups,
shot maps, best-player ratings, head-to-head record, live odds and pre-match
form. You can also fetch a specific match by its Sofascore event ID, or pull
every match currently live in a sport right now.

> 💡 **Why it matters:** most Sofascore scrapers on the market return only
> the score and maybe basic stats. This one exposes lineups, shot maps with
> xG, and odds as separate, verified data points, the deepest single-actor
> coverage of Sofascore's public match data available today.

### 📊 Output

Real sample fields from a verified run (Osasuna 2-1 Real Madrid, LaLiga):

| Field | Type | Example |
|---|---|---|
| 🖼 `imageUrl` | string | `https://api.sofascore.com/api/v1/team/2820/image` |
| 🆔 `matchId` | integer | `14081794` |
| 🏆 `tournament` | string | `LaLiga` |
| 🌍 `country` | string | `Spain` |
| 🏠 `homeTeam` / 🚩 `awayTeam` | string | `Osasuna` / `Real Madrid` |
| 🔢 `homeScore` / `awayScore` | number | `2` / `1` |
| 📶 `status` | string | `Ended` |
| 🕒 `startTime` | string (ISO) | `2026-02-21T17:30:00.000Z` |
| 📈 `hasXg` | boolean | `true` |
| 📊 `statistics` | array | 48 line items: `{"group":"Match overview","stat":"Ball possession","home":"39%","away":"61%"}` |
| 🧑‍🤝‍🧑 `lineups` | object | `{"home":{"formation":"4-3-3","startingXI":[11 players]}, "away":{...}}` |
| 🎯 `shotmap` | array | 26 shots: `{"player":"Vinícius Júnior","shotType":"goal","xg":0.34,...}` |
| ⭐ `playerRatings` | object | `{"bestHomePlayer":{"name":"...","rating":"7.8"},"bestAwayPlayer":{...}}` |
| ⚔️ `h2hRecord` | object | `{"homeWins":1,"awayWins":7,"draws":2}` |
| 💰 `odds` | array | `{"outcome":"1","odds":"7/2"}, {"outcome":"X","odds":"3/1"}, {"outcome":"2","odds":"7/10"}` |
| 📋 `pregameForm` | object or `"N/A"` | `{"home":{"avgRating":"6.82","recentForm":["W","W","D","W","D"]},...}` |
| 🕒 `scrapedAt` | string (ISO) | `2026-09-12T01:27:09.328Z` |
| ❌ `error` | string or `null` | `null` |

Any extra you don't enable returns `"Not Requested"` instead of an empty or
missing field, and an extra Sofascore genuinely doesn't have for a given
match (older fixtures often lack pre-match form) returns `"N/A"`, you always
know why a field is empty, never guess.

### ✨ Why choose this Actor

- **Seven optional extras, not one bundled dump.** Turn on only what you
  need; each is billed separately, so you never pay for data you didn't ask
  for.
- **Shot maps with real xG/xGOT per attempt**, most Sofascore actors on the
  market don't expose this at all.
- **11 sports from one Actor**, not a separate scraper per sport.
- **Honest ceilings.** Sofascore's calendar-by-date endpoint doesn't work on
  any date tested; this Actor doesn't pretend otherwise. Discovery is by
  team name, by live-right-now, or by direct match ID, and the README says
  so up front instead of you finding out after buying.

### 📈 How it compares to alternatives

Measured against the closest published Sofascore actors on the Apify Store:

| Actor | Primary price | Billable events |
|---|---|---|
| Market leader (84 users/30d) | $2.00 / 1,000 results | 2 (result + a bundled detail enrichment) |
| Closest full-stats competitor | $8.00 / 1,000 results | 1 |
| Tennis/football combo actor | $5.00 / 1,000 results | 5 (result, match detail, player profile, h2h, all surcharges) |
| **This Actor** | see pricing below | **8** (base match + 7 independently billed extras) |

No competitor measured breaks out shot maps or live odds as their own data
point. Both are unique to this Actor in the niche as of this writing.

### 🚀 How to use

1. Create a free [Apify account](https://console.apify.com). New accounts get $5 in free credit.
2. Open the Sofascore Match Stats Scraper and enter a team name (e.g. "Real Madrid") or a specific match ID.
3. Toggle on the extras you need. Statistics is on by default; the rest are opt-in.
4. Click **Start** and wait for the run to finish.
5. Download your data as CSV, Excel, JSON or XML, or pull it via the API.

### 💼 Business use cases

**Sports media & content**
Auto-generate post-match recap stats, lineup graphics, and shot-map
visualizations without manually copying numbers off a live site.

**Fantasy sports & betting research tools**
Feed player ratings, lineups and historical head-to-head records into
projection models, or track live odds movement across matches.

**Sports analytics platforms**
Build historical statistics databases across 11 sports from one consistent
schema instead of maintaining a separate scraper per sport.

**Agencies & data resellers**
Package match data feeds for clients who need structured sports data without
building and maintaining their own Sofascore integration.

### 🔌 Automating Sofascore Match Stats Scraper

Connect this Actor to **Make**, **Zapier**, **Slack**, or **Airbyte** to push
fresh match data into a spreadsheet, database, or channel automatically after
each run. Schedule the Actor to run daily or after matches finish, then route
the output dataset into **Google Drive** or a webhook for downstream
processing.

### 🌟 Beyond business use cases

**Research:** academic or independent research into match dynamics, xG
accuracy, or home/away performance patterns across leagues.
**Personal projects:** build your own live-score dashboard or fantasy
league tracker.
**Non-profit:** grassroots sports organizations tracking league statistics
without a data budget.
**Experimentation:** test sports-prediction models against real historical
statistics and odds.

### 🤖 Ask an AI assistant about this scraper

Paste this Actor's Store page into ChatGPT, Claude, or Perplexity and ask:
"What fields does this Sofascore scraper return, and how do I get shot maps
with expected goals for a specific match?" The Actor's README and input
schema are structured so AI assistants can answer accurately from the page
alone.

### ❓ Frequently Asked Questions

**Does this scraper work for sports other than football?**
Yes, basketball, tennis, American football, ice hockey, baseball, rugby,
esports, volleyball, handball and table tennis are all confirmed working via
the live-match discovery mode.

**Can I get matches for a specific calendar date?**
Not directly, Sofascore's own date-based schedule endpoint doesn't return
data for any date tested (confirmed, not a gap in this Actor). Use a team
name, live-right-now mode, or a direct match ID instead.

**What are shot maps and does every match have one?**
A shot map is every shot taken in a match with player, body part, situation
and expected goals (xG). It's available for football, basketball and
handball; other sports return `"N/A"` since Sofascore doesn't track it for
them.

**Are the betting odds live or historical?**
The odds returned are Sofascore's own live bookmaker market data for the
match's full-time result. This is informational sports data, not betting
advice.

**Why does pregameForm sometimes say "N/A"?**
Sofascore only keeps pre-match form data for a rolling window around the
match date. Older fixtures genuinely don't have it anymore, this Actor
reports that honestly instead of returning stale or fabricated data.

**How do I find a Sofascore match ID?**
It's the number in a match's Sofascore URL, e.g.
`sofascore.com/.../id:12345678`, copy the digits after `id:`.

**Does this Actor need cookies or a Sofascore account?**
No. Every field comes from Sofascore's own public match API; no login or
session is required.

**What happens if I enable an extra a match doesn't have?**
You get `"N/A"` for that field, and you're not charged for that extra on that
row, you only pay for data you actually received.

**Can I search by player name instead of team?**
Not in this version, team name, match ID, and live-by-sport are the three
supported ways to find matches.

**How fresh is the live match data?**
Live mode reflects Sofascore's live feed in real time at the moment the
Actor runs, including live scores and in-play odds.

### 🔌 Integrate with any app

Every run's output is available as CSV, Excel, JSON or XML, or through
Apify's API and client libraries for Python and JavaScript, pipe match data
straight into a spreadsheet, database, or your own application.

### 🔗 Recommended Actors

Browse the rest of the [PunkRecordsData](https://apify.com/punkrecordsdata)
catalog for more scrapers covering social media, marketplaces and pricing
intelligence.

> 💡 **Pro Tip:** browse the complete [PunkRecordsData collection](https://apify.com/punkrecordsdata).

**🆘 Need Help?** contact.punkrecordsdata@gmail.com

> **⚠️ Disclaimer:** This is an independent tool, not affiliated with,
> endorsed by, or sponsored by Sofascore. It collects only publicly
> available match data. Odds data is informational only and not betting
> advice.

# Actor input Schema

## `teamNames` (type: `array`):

Team names to look up (e.g. "Real Madrid"). Resolved to the team's Sofascore id via search, then its recent and upcoming fixtures are collected.

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

Specific Sofascore match IDs to fetch directly, bypassing team search. Find an ID in a Sofascore match URL, e.g. sofascore.com/.../id:12345678.

## `sport` (type: `string`):

Used only with "Live matches only" below, to pull every live match in this sport right now.

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

Ignore Team names / Event IDs and instead fetch every match currently live in the sport selected above.

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

Free users: limited to 10 matches (preview). Paid users: optional, max 1,000,000.

## `includeStatistics` (type: `boolean`):

Possession, shots, cards and other aggregated team stats.

## `includeLineups` (type: `boolean`):

Starting XI, formation, substitutes for both teams.

## `includeShotmap` (type: `boolean`):

Every shot in the match: player, position, outcome. Football/basketball/handball only — other sports return an empty array.

## `includePlayerRatings` (type: `boolean`):

Per-player performance rating for the match.

## `includeH2h` (type: `boolean`):

Historical wins/draws/losses between the two teams.

## `includeOdds` (type: `boolean`):

Live bookmaker odds for the match result market. Informational data only, not betting advice.

## `includePregameForm` (type: `boolean`):

Recent results and average rating for both teams heading into the match.

## Actor input object example

```json
{
  "teamNames": [
    "Real Madrid"
  ],
  "sport": "football",
  "liveOnly": false,
  "maxItems": 10,
  "includeStatistics": true,
  "includeLineups": false,
  "includeShotmap": false,
  "includePlayerRatings": false,
  "includeH2h": false,
  "includeOdds": false,
  "includePregameForm": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Key match fields: teams, score, tournament, status

## `fullData` (type: `string`):

Complete dataset with all 22 fields, including every requested extra

# 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 = {
    "teamNames": [
        "Real Madrid"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("punkrecordsdata/sofascore-match-stats-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 = {
    "teamNames": ["Real Madrid"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("punkrecordsdata/sofascore-match-stats-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 '{
  "teamNames": [
    "Real Madrid"
  ],
  "maxItems": 10
}' |
apify call punkrecordsdata/sofascore-match-stats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,punkrecordsdata/sofascore-match-stats-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/Xx5ZVjhzDEs4w8VpQ/builds/v9JI01ShKOGj6iZU6/openapi.json
