SofaScore Scraper – Live Scores, Fixtures & Match Stats avatar

SofaScore Scraper – Live Scores, Fixtures & Match Stats

Pricing

from $1.00 / 1,000 dataset rows

Go to Apify Store
SofaScore Scraper – Live Scores, Fixtures & Match Stats

SofaScore Scraper – Live Scores, Fixtures & Match Stats

Scrape SofaScore for live scores, fixtures, results, league tables and team or player profiles. One flat row per match: tournament, kick-off, both teams, score, status, venue, referee. Add match statistics, lineups, incidents, odds, votes, head-to-head. 17 sports. No API key needed.

Pricing

from $1.00 / 1,000 dataset rows

Rating

0.0

(0)

Developer

R.L.

R.L.

Maintained by Community

Actor stats

0

Bookmarked

39

Total users

18

Monthly active users

4 days ago

Last modified

Categories

Share

What does this SofaScore scraper do?

SofaScore Scraper pulls live scores, fixtures and results, deep match detail, league tables, and team & player data straight from SofaScore's own backend REST API — the same one the official mobile app talks to. It covers 17 sports — football, basketball, tennis, ice hockey, cricket, esports, motorsport and more. Because it hits the API directly instead of rendering pages, it's fast, cheap, and returns clean structured JSON rather than scraped HTML.

Run it on the Apify platform for scheduling, a REST API to pull results, webhooks and integrations, and one-click dataset export to JSON, CSV or Excel — no script to babysit.

What data can it pull from SofaScore?

  • Live scores for any sport, updated in real time.
  • Fixtures & results by date range, or by league season.
  • Full match detail enriched on demand with:
    • Statistics — possession, shots, passes, xG and more
    • Lineups — formations, starters/bench, per-player match ratings
    • Incidents — goals, cards, substitutions, period markers
    • Odds — pre-match betting markets
    • Win-probability votes — crowd 1 / X / 2 tallies
    • Head-to-head — historical record between the two teams
  • League tables (standings) — full or home/away splits.
  • Team profiles — venue, manager, colours, and the full squad.
  • Player profiles — position, market value, height, preferred foot, contract.
  • Search — resolve any team, player or tournament name to its SofaScore ID.
  • Paste-a-URL mode — drop in any SofaScore match/team/player/tournament link and it's routed automatically.
  • 17 sports, one Actor.

How do I run it?

  1. Click Try for free / Start on the Actor page.
  2. Pick a Mode (see the table below).
  3. Fill in the fields that mode needs — most are dropdowns or ID pickers.
  4. Click Start and open the Dataset tab when it finishes (export as JSON, CSV, Excel, HTML…).

Finding IDs: run search mode first (e.g. "real madrid") to get the numeric entityId for a team, player or tournament — then feed it to team, player, standings or tournament mode. Or just paste the page URL into url mode and skip IDs entirely.

What does each mode return?

Every dataset row carries a kind field identifying its shape (event, event_detail, search_result, standings_row, team, player). Wherever SofaScore has a matching web page, the row also carries a url linking to it (standings rows additionally include a tournamentUrl).

live — live scores

{ "mode": "live", "sport": "football" }
{
"kind": "event", "id": 16860578, "slug": "port-city-fc-golden-warriors-fc",
"startTimestamp": 1755532800, "sport": "football", "tournament": "NPSL",
"homeTeam": "Port City FC", "awayTeam": "Golden Warriors FC",
"homeScore": 1, "awayScore": 0, "statusType": "inprogress", "statusDescription": "2nd half"
}

scheduled — fixtures & results by date

{ "mode": "scheduled", "sport": "football", "dateFrom": "2026-08-18", "dateTo": "2026-08-18", "maxPages": 3 }

Returns one event row per match on each day in the range (same shape as live). Turn on fetchEventDetails to fan out to full match detail per event.

event_detail — full match detail, with enrichments

{
"mode": "event_detail", "eventIds": ["16363633"],
"includeStatistics": true, "includeLineups": true, "includeIncidents": true,
"includeVotes": true, "includeH2H": true, "includeOdds": true
}
{
"kind": "event_detail", "id": 16363633, "homeTeam": "Arsenal", "awayTeam": "Coventry City",
"homeScore": 3, "awayScore": 0, "statusType": "finished",
"statistics": [{ "period": "ALL", "groups": [{ "groupName": "Match overview",
"statisticsItems": [{ "name": "Ball possession", "home": "64%", "away": "36%", "key": "ballPossession" }] }] }],
"lineups": { "confirmed": true, "home": { "formation": "4-2-3-1",
"players": [{ "player": { "name": "David Raya", "position": "G" }, "statistics": { "rating": 7 } }] } },
"incidents": [{ "incidentType": "period", "text": "FT", "homeScore": 3, "awayScore": 0, "time": 90 }],
"odds": [{ "marketName": "Full time", "choices": [{ "name": "1", "fractionalValue": "1/5", "winning": true }] }],
"votes": { "vote1": 110530, "voteX": 8116, "vote2": 7638 },
"h2h": { "teamDuel": { "homeWins": 1, "awayWins": 0, "draws": 0 } },
"url": "https://www.sofascore.com/event/16363633"
}

Each enrichment toggle nests SofaScore's native payload under a key of the same name (statistics, lineups, incidents, odds, votes, h2h). Enabling any of them fetches full match detail automatically. The same toggles work in live, scheduled, tournament and url modes.

standings — league table

{ "mode": "standings", "uniqueTournamentId": 17, "standingsType": "total" }
{
"kind": "standings_row", "tournament": "Premier League", "uniqueTournamentId": 17,
"standingsType": "total", "position": 1, "teamId": 17, "team": "Manchester City",
"matches": 3, "wins": 3, "draws": 0, "losses": 0, "scoresFor": 7, "scoresAgainst": 2,
"points": 9, "promotion": "Champions League",
"url": "https://www.sofascore.com/football/team/manchester-city/17",
"tournamentUrl": "https://www.sofascore.com/football/tournament/england/premier-league/17"
}

One row per team. Leave seasonId empty for the current season, or set it for a historical table. standingsType can be total, home or away.

Only leagues and group/league phases have a table. Pure knockout cups (Copa Argentina, US Open Cup, …) have no standings on SofaScore, so the run ends with a status message telling you so instead of crashing -- use tournament mode for their fixtures and results instead.

tournament — a league season's fixtures & results

{ "mode": "tournament", "uniqueTournamentId": 17, "eventsSpan": "last", "maxPages": 3 }

Returns event rows for a whole league season — eventsSpan: "last" for played results, "next" for upcoming fixtures. Combine with the enrichment toggles for a full stats sweep of a competition.

team — team profile (+ optional squad)

{ "mode": "team", "teamId": 42, "includeSquad": true }
{
"kind": "team", "id": 42, "name": "Arsenal", "country": "England",
"primaryTournament": "Premier League", "managerName": "Mikel Arteta",
"venue": "Emirates Stadium", "venueCapacity": 60704,
"squad": [{ "id": 804508, "name": "Viktor Gyökeres", "position": "F", "jerseyNumber": "14" }],
"url": "https://www.sofascore.com/football/team/arsenal/42",
"team": { "…": "full native SofaScore team object nested here" }
}

player — player profile

{ "mode": "player", "playerId": 804508 }
{
"kind": "player", "id": 804508, "name": "Viktor Gyökeres", "position": "F",
"team": "Arsenal", "country": "Sweden", "height": 187, "preferredFoot": "Right",
"marketValue": 61000000, "marketValueCurrency": "EUR",
"url": "https://www.sofascore.com/player/viktor-gyokeres/804508",
"player": { "…": "full native SofaScore player object nested here" }
}

search — resolve names to IDs

{ "mode": "search", "searchQuery": "real madrid" }
{ "kind": "search_result", "resultType": "team", "entityId": 2829, "entityName": "Real Madrid", "sport": "football" }
{ "kind": "search_result", "resultType": "player", "entityId": 826643, "entityName": "Kylian Mbappé", "teamId": 2829 }
{ "mode": "url", "urls": [
"https://www.sofascore.com/team/football/arsenal/42",
"https://www.sofascore.com/player/viktor-gyokeres/804508"
] }

Match, team, player and tournament links are each routed to the right fetch and returned in their matching kind shape.

Which leagues and sports does it cover?

standings and tournament mode take a uniqueTournamentId. These are the ones people ask for most — all verified against SofaScore's own search endpoint:

CompetitionSportuniqueTournamentId
Premier League (England)football17
LaLiga (Spain)football8
Serie A (Italy)football23
Bundesliga (Germany)football35
Ligue 1 (France)football34
UEFA Champions Leaguefootball7
UEFA Europa Leaguefootball679
FIFA World Cupfootball16
NBAbasketball132
NFLamerican-football9464
NHLice-hockey234
Indian Premier Leaguecricket11165

Names repeat across sports and countries, so check the sport before you trust an ID: 35 is the German football Bundesliga, 149 is the German handball Bundesliga. For anything not in the table, run search mode with the competition name and read entityId off the uniqueTournament result, or paste the league's SofaScore URL into url mode.

live and scheduled mode take a sport slug instead. All 17 accepted values: football, basketball, tennis, ice-hockey, cricket, esports, motorsport, handball, volleyball, baseball, american-football, rugby, futsal, table-tennis, badminton, snooker, darts.

What does each input field do?

FieldTypeUsed byDescription
modeselectalllive, scheduled, event_detail, search, standings, tournament, team, player, url
sportselectlive, scheduledSport slug (football, basketball, tennis, …)
dateFrom / dateTodatescheduledYYYY-MM-DD range (inclusive)
maxPagesintegerscheduled, tournamentPages to sweep
eventIdsarrayevent_detailMatch IDs to fetch
searchQuerystringsearchTeam / player / tournament name
urlsarrayurlSofaScore links to route
uniqueTournamentIdintegerstandings, tournamentLeague ID (17 = Premier League)
seasonIdintegerstandings, tournamentOptional; current season if empty
standingsTypeselectstandingstotal / home / away
eventsSpanselecttournamentlast (results) / next (fixtures)
teamIdintegerteamTeam ID
includeSquadbooleanteamAlso fetch the squad
playerIdintegerplayerPlayer ID
fetchEventDetailsbooleanlive, scheduled, tournamentFan out to full match detail
includeStatistics / includeLineups / includeIncidents / includeOdds / includeVotes / includeH2Hbooleanevent modesPer-match enrichments (auto-enable detail fetch)
maxItemsintegerallStop after N rows (0 = unlimited)
requestDelaySecsnumberallDelay between API calls
proxyConfigurationobjectallResidential proxy on by default (see below)

What does a run cost?

Pay-per-result, charged only for what's actually produced (plus standard Apify platform usage):

  • $1 per 1,000 dataset rows ($0.001/row) — every event, standings, team, player or search row.
  • $0.50 per 1,000 enrichments ($0.0005 each) — one charge per per-match enrichment fetched (statistics, lineups, incidents, odds, votes, h2h). A plain run with no enrichments is billed at the row rate only; a match with all six enrichments on costs the row plus six enrichment charges (~$0.004 total).

Use maxItems / maxPages, and enable only the enrichments you need, to cap spend on wide sweeps.

How do I keep runs fast and cheap?

  • Run search once to grab the IDs you need, or skip IDs entirely with url mode.
  • For a fast overview, leave enrichments off; switch them on only when you need the depth.
  • page=1 is the first page of scheduled events for a date — page=0 always returns empty (an undocumented API quirk).
  • Residential proxy is enabled by default because the API is fronted by Cloudflare and blocks datacenter IPs; leave it on unless you're running from an IP Cloudflare already trusts.
  • Schedule the Actor (hourly/daily) via Apify Schedules for always-fresh data.

What do these SofaScore terms mean?

  • uniqueTournamentId — SofaScore's stable numeric id for a competition (the Premier League as an institution). A tournamentId in a raw payload can be a single season's instance; the unique id is the one this Actor takes as input.
  • seasonId — one edition of that competition. Leave it empty and the Actor resolves the current season; set it for a historical table or a past season's fixtures. Every event row carries the seasonId it belongs to, so you can read past ids off a result.
  • kind — added by this Actor (not SofaScore) to every row, naming the row's shape: event, event_detail, standings_row, team, player, search_result.
  • statusType — SofaScore's status bucket, passed through unchanged: notstarted, inprogress, finished, postponed, canceled, interrupted. statusDescription is the human label next to it ("2nd half", "FT").
  • standingsType — total is the full league table; home and away are the same table computed from home-only or away-only results.
  • Enrichment — one extra per-match API call for depth SofaScore does not put in the fixture list: statistics, lineups, incidents, odds, votes or h2h.
  • xG (expected goals) — a shot-quality model score that appears inside the statistics payload; it estimates how many goals an average team would score from the chances taken.
  • Head-to-head (h2h) — the historical win/draw/loss record between the two teams in this fixture.
  • Votes — SofaScore users' pre-match 1 / X / 2 poll tallies, not a bookmaker's line.

FAQ

Do I need a SofaScore account, login or API key? No. The Actor calls SofaScore's public, unauthenticated backend endpoints — there is nothing to register and no key to paste. An Apify account is all you need.

What exactly is in one row? It depends on the mode, and every row says which shape it is in its kind field. An event row is one match flattened to a single level: id, slug, startTimestamp, sport, tournament, uniqueTournament, uniqueTournamentId, seasonId, category, country, round, roundName, both teams' …TeamId / …Team / …TeamSlug / …TeamCountry, homeScore, awayScore, statusCode, statusType, statusDescription, venue, venueCity, referee and url.

Can I get match statistics and lineups, not just the scoreline? Yes — that is what the enrichment toggles are for, and they work in live, scheduled, tournament, url and event_detail mode. Each one nests SofaScore's own payload under a key of the same name.

Can I get past seasons, or only the current one? Past seasons too. Set seasonId on standings or tournament mode; leave it empty and you get the current season.

Can I schedule it and pull the data into my own system? Yes. Use Apify Schedules for hourly or daily runs, and the Apify API or a webhook to collect each run's dataset — or export manually to JSON, CSV or Excel from the Dataset tab.

What happens when something goes wrong? Nothing crashes out silently. An id SofaScore has no data for, a missing required field, or a knockout cup with no league table ends the run with a status message explaining which input was wrong. A single page or enrichment that fails after retries is logged as a warning and the run keeps everything else it collected, rather than throwing the whole dataset away.

Is this an official SofaScore API? No. SofaScore does not license API access, so treat this as an unofficial integration of a public, unauthenticated endpoint (access-control-allow-origin: *, no login). It is provided for research and legitimate data-integration use, and you are responsible for complying with SofaScore's Terms of Service in your jurisdiction.

Found a bug or need a custom field or endpoint? Open an issue in the Actor's Issues tab.

Did you find this useful?

⭐ Rate this Actor on Apify! Your feedback helps other users find it and helps us keep improving it.