SofaScore Scraper | Live Scores & Match Data API
Pricing
from $0.90 / 1,000 results
SofaScore Scraper | Live Scores & Match Data API
[💰 $0.9 / 1K] Scrape live scores, fixtures, lineups, statistics, odds, and standings from SofaScore. Search by team/player/tournament, paste match links, or pull every live or scheduled match across any sport.
Pricing
from $0.90 / 1,000 results
Rating
0.0
(0)
Developer
ParseBird
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
SofaScore Scraper
Scrape SofaScore — live scores, fixtures, lineups, statistics, odds, and standings — by team, player, or tournament keyword, by pasting match links, or by pulling every live or scheduled match for any sport.
| Search, paste links, or pull every live/scheduled match, then enrich each one with statistics, lineups, incidents, odds, fan votes, standings, and squads — with built-in change-tracking for recurring monitoring campaigns. |
Copy to your AI assistant
Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.
parsebird/sofascore-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/sofascore-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: mode (string, "search"/"url"/"live"/"scheduled"), searchQueries (string array, default ["Real Madrid"], search mode), searchType ("all"/"team"/"player"/"tournament"/"match"), urls (string array, url mode — team/player/tournament/match links; match links need "#id:<number>" or "/event/<number>"), sports (string array, default ["football"], live/scheduled modes), date (string, "YYYY-MM-DD" or "today", scheduled mode), daysAhead (integer, default 0), includeStatistics/includeLineups/includeIncidents (boolean, default true), includeOdds/includeVotes/includeSquad (boolean, default false), includeStandings (boolean, default true), maxItems (integer, default 20, 0=unlimited), resumeFromRunId (string, continue an interrupted crawl), incrementalMode (boolean, tags records NEW/CHANGED/UNCHANGED), stateKey (string, name a monitoring campaign), emitUnchanged/emitExpired (boolean, default false). Output fields vary by type ("match"/"team"/"player"/"tournament"): id, name, sport, homeTeam/awayTeam, homeScore/awayScore, statusType, startTimestamp, tournament/uniqueTournament, season, round, venue, referee, statistics/lineups/incidents/odds/votes/standings/squad (when enabled), url, raw. Full actor spec: fetch build via GET https://api.apify.com/v2/acts/parsebird~sofascore-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
What does SofaScore Scraper do?
This Actor scrapes SofaScore, the live-score platform covering football, tennis, basketball, and dozens of other sports, by rendering its internal API in a real browser — SofaScore blocks plain HTTP requests at the network-fingerprint level, so a browser is required to get through reliably.
- 🔎 Four modes — search by team/player/tournament/match keyword, paste SofaScore links directly, pull every match live right now, or every scheduled fixture across a date range
- 📊 Deep enrichment, opt-in — statistics, lineups with player ratings, incidents (goals/cards/subs), pre-match odds, fan prediction votes, full league standings, and complete squads
- 🔁 Incremental monitoring — tag every record
NEW,CHANGED, orUNCHANGEDagainst a previous run sharing the samestateKey, so recurring campaigns only pay attention to what actually moved - ▶️ Resumable crawls — pass a previous run's ID via
resumeFromRunIdto continue an interrupted large crawl without re-fetching or re-billing what it already collected - ⏱️ Scheduling — run this Actor on a timer via Apify Scheduler for live-score monitoring or daily fixture digests
- 🔌 API access — trigger runs and pull results programmatically via the Apify API or client libraries
- 📊 Flexible export — download results as JSON, CSV, or Excel, or query them via API
What data can you extract from SofaScore?
| Field | Description |
|---|---|
type | match, team, player, or tournament |
name / homeTeam / awayTeam | Match or entity name |
homeScore / awayScore / homeScoreHalftime / awayScoreHalftime | Scores, full-time and half-time |
statusType / winnerCode | Match state (notstarted, inprogress, finished) and result |
tournament / uniqueTournament / season / round | Competition context |
venue / venueCity / latitude / longitude / referee / attendance | Match logistics |
statistics / lineups / incidents / odds / votes | Match detail, when enabled |
standings / squad | Tournament table / team roster, when enabled |
url | Direct link back to the SofaScore page |
Input parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
mode | string | No | search | search, url, live, or scheduled |
searchQueries | string array | No | ["Real Madrid"] | Keywords to resolve (search mode) |
searchType | string | No | all | Restrict a query to team, player, tournament, or match |
urls | string array | No | sample links | SofaScore links (url mode) |
sports | string array | No | ["football"] | Sports for live and scheduled modes |
date | string | No | today | YYYY-MM-DD for scheduled mode |
daysAhead | integer | No | 0 | Extra days after date |
includeStatistics | boolean | No | true | Match and player statistics |
includeLineups | boolean | No | true | Match lineups and ratings |
includeIncidents | boolean | No | true | Goals, cards, substitutions |
includeOdds | boolean | No | false | Pre-match odds markets |
includeVotes | boolean | No | false | Fan prediction poll per match |
includeStandings | boolean | No | true | Tournament league tables |
includeSquad | boolean | No | false | Full team squads |
maxItems | integer | No | 20 | Stop after this many records. 0 = no limit |
resumeFromRunId | string | No | — | Continue one interrupted crawl |
incrementalMode | boolean | No | false | Recurring change detection |
stateKey | string | No | — | Name/share an incremental-mode monitoring campaign |
emitUnchanged | boolean | No | false | Also return (and bill) UNCHANGED entities |
emitExpired | boolean | No | false | Also return (and bill) EXPIRED entities |
proxy | object | No | Apify proxy | Connection settings |
Output example
{"type": "match","id": 16246416,"sport": "football","name": "Indonesia - Vietnam","homeTeam": "Indonesia","awayTeam": "Vietnam","homeScore": 0,"awayScore": 2,"statusType": "inprogress","winnerCode": null,"startTimestamp": 1785763800,"tournament": "ASEAN Championship, Group A","uniqueTournament": "ASEAN Championship","season": "2026","round": 4,"venue": "Pakansari Stadium","venueCity": "Bogor Regency","referee": "Timothy Danaskos","country": "Asia","url": "https://www.sofascore.com/football/match/vietnam-indonesia/EWbsaQc#id:16246416","hasXg": false,"incidents": [{ "incidentType": "goal", "time": 23, "player": { "name": "Player Name" } }],"raw": {}}
Download results in JSON, CSV, or Excel directly from the Apify Console, or pull them programmatically via the API.
Use cases
- Live-score monitoring — poll
mode: "live"on a schedule to power a dashboard or alerting pipeline - Fixture digests — pull
mode: "scheduled"for the day (plusdaysAhead) to build a daily or weekly preview - Competitor/brand research — pull a team or player's full profile, squad, and standings context in one call
- Change-tracked monitoring — run
incrementalModeon a schedule with a sharedstateKeyto get only what changed since the last check, instead of re-processing everything every time - Betting/analytics research — combine
includeOddsandincludeVoteswith match statistics for pre-match analysis
How to scrape SofaScore with this Actor
- Go to the SofaScore Scraper page on Apify Store
- Click Try for free — new users get a free trial to test the Actor before paying
- Pick a mode — search by keyword, paste links, live, or scheduled
- Toggle the enrichments you need (statistics, lineups, incidents, odds, votes, standings, squad)
- Set
maxItemsto cap the run size (or0for unlimited) - Click Start — the Actor renders SofaScore's own API in a real browser and normalizes every result
- When the run finishes, download your data as JSON, CSV, or Excel, or fetch it via the API
Use with the Apify API
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run = client.actor("parsebird/sofascore-scraper").call(run_input={"mode": "live","sports": ["football"],"includeStatistics": True,"includeIncidents": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{item['name']} - {item['homeScore']}:{item['awayScore']} ({item['statusType']})")
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });const run = await client.actor('parsebird/sofascore-scraper').call({mode: 'live',sports: ['football'],includeStatistics: true,includeIncidents: true,});const { items } = await client.dataset(run.defaultDatasetId).listItems();items.forEach((item) => {console.log(`${item.name} - ${item.homeScore}:${item.awayScore} (${item.statusType})`);});
See the Apify API documentation for full reference, or the Actor's API tab for ready-to-run request snippets in more languages.
How much does it cost to scrape SofaScore?
This Actor uses Pay-per-event pricing with two events — you only pay for records actually returned, with no separate platform rental fee.
| Event | Price per event (Free plan) | Price per 1,000 |
|---|---|---|
record-scraped | $0.0015 | $1.50 |
detail-enrichment | $0.0009 | $0.90 |
record-scraped is charged once per match, team, player, or tournament pushed to the dataset. detail-enrichment is charged once more on top, only when at least one enrichment (statistics, lineups, incidents, odds, votes, standings, or squad) was actually attached. A 1,000-match run with statistics and incidents enabled costs about $2.40 on the Free plan. Start with the free trial and a low maxItems to preview results before scaling up.
FAQ
Why does SofaScore need a browser instead of a simple API call? SofaScore blocks non-browser HTTP clients at the network-fingerprint level — the same request that returns real data from a browser returns a 403 from a plain HTTP library. This Actor renders every request in a real headless browser to get through reliably.
Why does this Actor default to a country-pinned residential proxy? SofaScore also blocks by IP reputation: even a real headless browser gets a 403 from a datacenter IP, and an unpinned residential proxy pool can return a similarly flagged IP. Pinning to a specific country's residential pool (US by default) reliably avoids this — confirmed by direct testing on Apify's own infrastructure.
How does searchType: "match" work?
SofaScore's own search only returns match results for match-shaped queries (e.g. "Real Madrid Barcelona" or "Real Madrid vs Barcelona"), not for a single team/player name — that's how the underlying search behaves, not a limitation of this Actor.
What happens with mode: "scheduled" under the hood?
SofaScore's site no longer exposes a single "all matches for date X" endpoint — it first looks up which tournaments have matches that day, then fetches each tournament's events for that date separately. This Actor reproduces that same two-step lookup, which makes scheduled mode slower than live or url mode, especially across many sports or several daysAhead.
How does incremental mode decide NEW vs. CHANGED vs. UNCHANGED?
Each record's content (excluding the raw upstream object) is hashed and compared against the previous run that used the same stateKey. No previous record with that ID → NEW. Same ID but a different hash → CHANGED. Same ID and hash → UNCHANGED (returned only if emitUnchanged is on). An ID seen in the previous run but absent from this one is EXPIRED (returned only if emitExpired is on, as a minimal placeholder record since fresh data for it isn't available).
What exactly does resumeFromRunId skip?
It reads the referenced run's dataset, builds a set of already-pushed type:id pairs, and skips those specific entities in this run — so a crawl that got cut off partway (e.g. a timeout on a huge scheduled run) can continue without re-fetching or re-billing what it already collected.
Can I schedule recurring runs?
Yes. Use Apify's Scheduler to run this Actor on a timer — pair it with incrementalMode and a fixed stateKey for change-tracked monitoring.
Is it legal to scrape SofaScore? SofaScore's match, team, and player pages are publicly viewable without a login. You're responsible for complying with SofaScore's Terms of Service for your specific use case. See Apify's blog post on the legality of web scraping for general background.
Can I access results via API? Yes. Every run's dataset is available through the Apify API and client libraries (Python, JavaScript) — see the Actor's API tab for ready-made snippets.
Something not working? Open an issue on the Actor's Issues tab in Apify Console — the ParseBird team monitors it directly.
Related Actors
Other sports and monitoring Actors from ParseBird:
- Polymarket Scraper — prediction-market odds and pricing data
- DexScreener Crypto Scraper — real-time market data monitoring
- HTTP Request Actor — general-purpose API/webhook integration