Sofascore Match Stats Scraper - Live Scores, Odds & Lineups
Pricing
from $10.00 / 1,000 match summaries
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
Maintained by CommunityActor stats
0
Bookmarked
10
Total users
3
Monthly active users
0.057 hours
Issues response
9 days ago
Last modified
Categories
Share
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 (
dateplusdaysAhead, 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.
| Group | Fields |
|---|---|
| Match | matchId, url, sport, status, startTime, winner, hasXg |
| Teams | homeTeam, awayTeam, homeTeamId, homeManager, awayManager |
| Score | homeScore, awayScore, by period, overtime and penalties, red cards |
| Venue and referee | venueName, venueCity, attendance, refereeName |
| Extras | statistics, lineups, shotmap (xG, xGOT), playerRatings, h2hRecord, odds, pregameForm, incidents, votes, standings |
| Team profile | name, country, managerName, foundationDate, recentForm, leaguePosition, venue, squad |
| Player profile | position, height, birthDate, preferredFoot, team, marketValue, contractUntil, transfers; tennis and darts add ranking and prize money |
| Competition profile | titleHolder, mostTitles, upperDivisions, lowerDivisions, seasons, standings |
| Search | searchQuery, resultType, searchScore, name, country, sport |
scrapedAt | scrape 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:
| Event | Price |
|---|---|
| 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
- Open the Actor and pick matches (team name, event IDs, tournament and season, date, or live) or profiles and search.
- Turn on the extras you need. Statistics is on by default.
- Click Start, then download the dataset as CSV, Excel, JSON or XML.
⚙️ Input
| Field | Meaning |
|---|---|
teamNames | Team names to look up. Default ["Real Madrid"]. |
eventIds | Specific Sofascore match IDs, from a match URL ending in id:12345678. |
sport | One of 11 sports, used for live and date modes. Default football. |
liveOnly | Fetch every live match in the chosen sport. |
tournaments + tournamentSeason | Competitions by name, id or id:seasonId, and the season ("25/26", a year or latest). |
date + daysAhead | Matches of a UTC date (YYYY-MM-DD) and 0 to 13 following days. |
gameWindow, dateFrom, dateTo | Played, upcoming or both, and a date range, for team and season runs. |
teamProfiles, playerProfiles, competitionProfiles | Names, ids or page URLs; one profile row each. |
searchQueries, searchType, searchFullProfiles | Names to search (two or more characters), result type, and full profiles for every hit. |
includeSquad, includeTransfers | Squad on team profiles; transfers on player profiles. Free for now. |
maxItems | Maximum rows. Default 10. Free users are capped at 10. |
includeStatistics, includeLineups, includeShotmap, includePlayerRatings, includeH2h, includeOdds, includePregameForm | Seven priced extras, each billed per match that has data. |
includeIncidents, includeVotes, includeStandings | Three extras, free for now. |
onlyNew, stateKey, resetSeen | Monitor 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.
| Capability | This Actor | abotapi | scrapesmith | parsebird |
|---|---|---|---|---|
| Profiles and search | Team, player, competition, search | Yes, plus raw object | Yes | Yes |
| Match depth | xG shot map, pre-match form, odds | No shot map stated | No shot map stated | No shot map stated |
| Change tracking | Only-new mode, no change columns | Yes | Not stated | Yes |
| Sports | 11 | 20+ | 10+ | Not stated |
| Price per 1,000 | Matches $10, $20 with statistics; profiles free for now | From $1.00 | From $0.70 | From $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.
🛡️ Is it legal to scrape 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