Sofascore Match Stats Scraper - Live Scores, Odds & Lineups avatar

Sofascore Match Stats Scraper - Live Scores, Odds & Lineups

Pricing

from $10.00 / 1,000 match summaries

Go to Apify Store
Sofascore Match Stats Scraper - Live Scores, Odds & Lineups

Sofascore Match Stats Scraper - Live Scores, Odds & Lineups

Scrape Sofascore match data for 11 sports: score, statistics, lineups, xG shot maps, player ratings, head-to-head and odds. Search by team, match ID or live. Export CSV, Excel, JSON or API. No login or API key. 22 fields per match, 7 optional extras.

Pricing

from $10.00 / 1,000 match summaries

Rating

0.0

(0)

Developer

RecordsData

RecordsData

Maintained by Community

Actor stats

0

Bookmarked

10

Total users

3

Monthly active users

0.057 hours

Issues response

9 days ago

Last modified

Share

RecordsData

Sofascore Match Stats Scraper collects Sofascore data for 11 sports: match rows (score, status, venue, referee, statistics, lineups, xG shot maps, player ratings, incidents, fan votes, standings, head-to-head, odds) plus team, player and competition profiles and search by name. Find matches by team name, match ID, tournament season, calendar date or live, get one row per match or profile, export CSV, Excel, JSON or API. No login, no API key. Pay per match and per extra, never for failed or empty rows; profiles, search, squads and transfers are free for now.

Sofascore Match Stats Scraper turns Sofascore's match pages into clean, typed rows: up to 60 columns of context per match plus up to 10 optional extras. It also returns profile rows for teams, players and competitions, and searches Sofascore by name. Every row starts with a recordType column (match, team, player or competition). It is built for sports analysts, fantasy and betting-research tools, sports media and LLM agents.

⚽ Sofascore match scraper: what does it do?

  • Find matches by team name, tournament season, calendar date (date plus daysAhead, 0 to 13), event ID, or live now.
  • Add statistics, lineups, xG shot maps, player ratings, head-to-head, odds, pre-match form, incidents, fan votes and the league table to the same row.
  • Get team, player and competition profiles and search by name; names resolve inside the chosen sport.
  • Monitor mode (onlyNew) returns only matches not seen before; skipped matches are not charged.

Supported sports: football, basketball, tennis, American football, ice hockey, baseball, rugby, esports, volleyball, handball and table tennis.

📊 Sofascore data you can extract

Match rows have up to 60 data columns; the schema has 126 typed columns. Error rows add errorType, hint and error and are never billed.

GroupFields
MatchmatchId, url, sport, status, startTime, winner, hasXg
TeamshomeTeam, awayTeam, homeTeamId, homeManager, awayManager
ScorehomeScore, awayScore, by period, overtime and penalties, red cards
Venue and refereevenueName, venueCity, attendance, refereeName
Extrasstatistics, lineups, shotmap (xG, xGOT), playerRatings, h2hRecord, odds, pregameForm, incidents, votes, standings
Team profilename, country, managerName, foundationDate, recentForm, leaguePosition, venue, squad
Player profileposition, height, birthDate, preferredFoot, team, marketValue, contractUntil, transfers; tennis and darts add ranking and prize money
Competition profiletitleHolder, mostTitles, upperDivisions, lowerDivisions, seasons, standings
SearchsearchQuery, resultType, searchScore, name, country, sport
scrapedAtscrape time

An extra you did not enable is returned as "Not Requested". An extra Sofascore does not have for that match is returned as "N/A" and is not billed.

🧾 Sofascore scraper sample output

One match from a cloud verification run (2026-10-04) (team search "Real Madrid", seven extras on), shortened:

{
"recordType": "match",
"matchId": 14081798,
"tournament": "LaLiga",
"homeTeam": "Real Madrid",
"awayTeam": "Getafe",
"homeScore": 0,
"awayScore": 1,
"status": "Ended",
"startTime": "2026-03-02T20:00:00.000Z",
"hasXg": true,
"statistics": [
{ "group": "Match overview", "stat": "Ball possession", "home": "77%", "away": "23%" }
],
"lineups": { "home": { "formation": "4-2-3-1" }, "away": { "formation": "5-4-1" } },
"shotmap": [
{ "player": "Mauro Arambarri", "team": "away", "minute": 90, "shotType": "save", "xg": 0.0115, "xgot": 0.1852 }
],
"playerRatings": { "bestHomePlayer": { "name": "Federico Valverde", "rating": "7.4" } },
"h2hRecord": { "homeWins": 8, "awayWins": 2, "draws": 0 },
"odds": [{ "outcome": "1", "odds": "9/25" }, { "outcome": "X", "odds": "15/4" }, { "outcome": "2", "odds": "17/2" }],
"scrapedAt": "2026-10-04T05:48:17.681Z"
}

A cloud run on 2026-10-10 searched "Haaland" and returned 5 player rows, each with recordType, searchQuery, resultType, searchScore and the player name.

💰 How much does it cost to scrape Sofascore?

Pay per event. You are charged only for rows that were saved and extras that returned real data. Error rows, "not found" rows, skipped already-seen matches and empty extras are free. Prices at the standard (FREE) tier:

EventPrice
Match summary (base row)$0.01
Match statistics$0.01
Lineup record$0.01125
Shot map$0.015
Player ratings$0.01
Head-to-head record$0.01
Betting odds$0.01
Pre-match form$0.01

Incidents, fan votes and standings (also the table on a competition profile) are free for now. Team, player and competition profiles, search rows, squads and transfers are free for now too: they have no price yet, so nothing is charged for them. Worked example at the FREE tier: with only the base row, 1,000 matches cost 1,000 x $0.01 = $10.00. With the default extra (statistics) a match costs $0.01 + $0.01 = $0.02, so 1,000 matches cost $20.00. With the seven priced extras on and data returned for each, a match costs $0.08625, so 1,000 matches cost $86.25. Higher Apify plans get lower prices on lineups and shot maps. Set a maximum run cost in the run options and the Actor stops cleanly when it is reached. 100 profiles or 100 search hits cost $0.00 today.

🚀 How to scrape Sofascore matches in 3 steps

  1. Open the Actor and pick matches (team name, event IDs, tournament and season, date, or live) or profiles and search.
  2. Turn on the extras you need. Statistics is on by default.
  3. Click Start, then download the dataset as CSV, Excel, JSON or XML.

⚙️ Input

FieldMeaning
teamNamesTeam names to look up. Default ["Real Madrid"].
eventIdsSpecific Sofascore match IDs, from a match URL ending in id:12345678.
sportOne of 11 sports, used for live and date modes. Default football.
liveOnlyFetch every live match in the chosen sport.
tournaments + tournamentSeasonCompetitions by name, id or id:seasonId, and the season ("25/26", a year or latest).
date + daysAheadMatches of a UTC date (YYYY-MM-DD) and 0 to 13 following days.
gameWindow, dateFrom, dateToPlayed, upcoming or both, and a date range, for team and season runs.
teamProfiles, playerProfiles, competitionProfilesNames, ids or page URLs; one profile row each.
searchQueries, searchType, searchFullProfilesNames to search (two or more characters), result type, and full profiles for every hit.
includeSquad, includeTransfersSquad on team profiles; transfers on player profiles. Free for now.
maxItemsMaximum rows. Default 10. Free users are capped at 10.
includeStatistics, includeLineups, includeShotmap, includePlayerRatings, includeH2h, includeOdds, includePregameFormSeven priced extras, each billed per match that has data.
includeIncidents, includeVotes, includeStandingsThree extras, free for now.
onlyNew, stateKey, resetSeenMonitor mode: only matches not seen before under this state key.
{
"tournaments": ["LaLiga"],
"tournamentSeason": "25/26",
"gameWindow": "played",
"dateFrom": "2026-03-01",
"dateTo": "2026-03-03",
"maxItems": 5,
"includeStatistics": true,
"includeIncidents": true
}

If you fill Event IDs, a tournament or a date and leave Team names at its default, the default team is skipped. A profile or search input takes precedence: match inputs and only-new mode are ignored in that run.

⚖️ Sofascore scraper vs alternatives

Read on 2026-10-10 from public Apify Store pages. "Not stated" means the page does not mention it.

CapabilityThis Actorabotapiscrapesmithparsebird
Profiles and searchTeam, player, competition, searchYes, plus raw objectYesYes
Match depthxG shot map, pre-match form, oddsNo shot map statedNo shot map statedNo shot map stated
Change trackingOnly-new mode, no change columnsYesNot statedYes
Sports1120+10+Not stated
Price per 1,000Matches $10, $20 with statistics; profiles free for nowFrom $1.00From $0.70From $0.90 ($1.50 record)

All three rivals also return profiles and search, so that gap is closed here, with 126 typed dataset columns. This Actor does not build change-tracking columns, a raw copy of the Sofascore object or team logos on match rows. Matches cost more per 1,000 than every rival, so for plain volume at the lowest price pick a rival. Pick this Actor when you need xG shot maps, pre-match form, odds and lineups in one row.

💼 Use cases

Post-match recap articles, fantasy and prediction models, betting research and multi-sport match databases.

🔌 Run via API, schedule and integrations

curl -X POST "https://api.apify.com/v2/acts/recordsdata~sofascore-match-stats-scraper/runs?token=YOUR_TOKEN" \
-H "content-type: application/json" \
-d '{"teamNames":["Real Madrid"],"maxItems":10}'

Use the Apify client for Python or JavaScript, schedule runs, and connect the dataset to Zapier, Make, n8n, Google Sheets or webhooks.

🤖 Sofascore Match Stats Scraper MCP server for AI agents

AI agents can call Sofascore Match Stats Scraper through the Apify MCP server at https://mcp.apify.com?tools=RecordsData/sofascore-match-stats-scraper. Add this to your MCP client configuration (Claude Desktop, Cursor, VS Code or any remote MCP client):

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=RecordsData/sofascore-match-stats-scraper"
}
}
}

Example agent prompt:

Use the Sofascore Match Stats Scraper to get the last 5 Real Madrid matches with statistics and the shot map turned on, then compare total xG for each team in each match. Then get the profile of Erling Haaland with his transfer history, and list tomorrow football fixtures with the league standings.

Tool description: choose Sofascore Match Stats Scraper when an agent needs per-match sports data from Sofascore: scores, team statistics, lineups, xG shot maps, best-player ratings, head-to-head, odds or pre-match form, for a team name, specific match IDs, a tournament season, a date or live matches. Also choose it for team, player or competition profiles and searches by name on Sofascore.

The Actor reads publicly available match data and does not log in. You are responsible for using the data in line with Sofascore's terms and local law. Odds are informational only. This is an independent tool, not affiliated with Sofascore.

❓ Frequently asked questions

Why does my Sofascore Match Stats Scraper run fail with HTTP 403 or "blocked"? In October 2026 Sofascore started answering HTTP 403 with reason "challenge" on its API host. Sofascore Match Stats Scraper now uses a Firefox browser fingerprint through a residential proxy, and a 403 is retried up to 8 times and a proxy tunnel error up to 16 times on a fresh IP. If every attempt is refused, the run ends FAILED with no charge, so try again later.

Why did Sofascore Match Stats Scraper return only 10 results when I asked for more? Free Apify accounts are capped at 10 rows per run (a preview), whatever maxItems says. The run log shows "Free user detected" and the run status says "the free plan stops at 10 rows". On a paid plan maxItems goes up to 1,000,000. With several names in teamNames, Sofascore Match Stats Scraper reads about 30 matches per team and page and keeps paging (up to 25 pages per team and direction) until maxItems is reached, taking turns between the teams. The run ends sooner only when the teams have fewer matches than maxItems, or when dateFrom and dateTo leave fewer.

Why did Sofascore Match Stats Scraper give me 0 results? The team name did not match a Sofascore team, or the team has no matches to return. The run then succeeds with a status message and zero cost. Check the spelling of the team name, or use a Sofascore event ID taken from a match URL instead. For a profile or search input, check the name, id or URL: a name not found gives one free error row with an errorType and a hint.

Can Sofascore Match Stats Scraper get matches for a calendar date? Yes. Set date (YYYY-MM-DD, UTC) and optionally daysAhead from 0 to 13. Sofascore Match Stats Scraper lists the competitions playing that day in Sofascore's priority order, so maxItems keeps the biggest fixtures first. Pick the sport with the sport input.

Can Sofascore Match Stats Scraper scrape a whole tournament season? Yes. Put a competition name, an id or id:seasonId in tournaments and a season such as "25/26", a year or latest in tournamentSeason. Narrow it with gameWindow, dateFrom and dateTo. Set maxItems to cap the cost of a long season, because each match is billed.

How does only-new mode work in Sofascore Match Stats Scraper? Switch on onlyNew and keep the same stateKey between runs. A match counts as new once per state: when it is upcoming, when it finishes, and on every score change while it is in progress. Already-seen matches are skipped before any request and are not charged. Use resetSeen to clear the memory. Profile and search inputs ignore it.

Does Sofascore Match Stats Scraper work for sports other than football? Yes. Sofascore Match Stats Scraper supports 11 sports: football, basketball, tennis, American football, ice hockey, baseball, rugby, esports, volleyball, handball and table tennis. Shot maps with xG exist only for football, basketball and handball, and extras Sofascore lacks are returned as N/A and not billed.

Are the odds from Sofascore Match Stats Scraper live? They are Sofascore's bookmaker odds for the full-time result market at the moment of the run, returned as fractional odds for outcomes 1, X and 2. Odds are not streamed, so schedule repeated runs if you want to track movement. They are informational only and not betting advice.

Why is pregameForm "N/A" in Sofascore Match Stats Scraper output? Sofascore keeps pre-match form only around the match date, so for older or distant matches Sofascore Match Stats Scraper returns N/A for that extra. In our 2026-10-07 verification run, pre-match form was available for 6 of 10 matches. An N/A extra is not billed.

How do I find a Sofascore match ID for Sofascore Match Stats Scraper? Open the match page on sofascore.com and look at the URL: the match ID is the number after id: at the end of the address, for example 12345678. Paste one or several IDs into the eventIds field and the default team is skipped.

Can Sofascore Match Stats Scraper get team and player profiles? Yes. Put a name, a Sofascore id or a page URL in teamProfiles, playerProfiles or competitionProfiles, and pick the sport that fits the name, because names are searched inside that sport. Add includeSquad for team squads or includeTransfers for a player's transfer history. Profiles are free for now.

Can Sofascore Match Stats Scraper search Sofascore by name? Yes. Fill searchQueries with names of two or more characters and set searchType to all, team, player or competition. Each hit becomes a row with resultType, searchScore, name, country and sport, or turn on searchFullProfiles for the full profile of every hit. Hits are de-duplicated and search rows are free for now.

Do I need a Sofascore account or cookies for Sofascore Match Stats Scraper? No. Sofascore Match Stats Scraper reads publicly available match data and does not log in, so there is no Sofascore account, API key or cookie to configure. You only need an Apify account. The actor handles the browser fingerprint and residential proxy itself.

🔗 Want more sports data? Other RecordsData scrapers

🆘 Support

Questions or a missing field? Open the Issues tab or write to contact.punkrecordsdata@gmail.com.

Last updated: 2026-10-11