FotMob Match Details Scraper
Pricing
from $10.00 / 1,000 match details results
FotMob Match Details Scraper
Scrape full FotMob match details: final score, lineups & formations, per-player stats and ratings, a goal/card/substitution timeline, the team-stat comparison, venue, referee and player of the match. One normalized JSON/CSV record per match. Failed lookups are never billed.
Pricing
from $10.00 / 1,000 match details results
Rating
0.0
(0)
Developer
Elena Vance
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
FotMob Match Details Scraper — Lineups, Per-Player Stats, Events & xG, in One Record
Turn any FotMob match into clean, structured JSON or CSV: the final score, both teams' formations and lineups, per-player statistics and ratings, a goal/card/substitution timeline, the full head-to-head team-stat comparison (possession, shots, xG, passing, duels…), plus venue, referee, attendance and player of the match — one rich, normalized record per match.
Give it one or more match ids (or match URLs), toggle exactly which sections you want, and get back the deepest per-match football data FotMob exposes — ready for a spreadsheet, database, model, or app. No login, no account, no HTML wrangling — and you are never billed for failed lookups.
Good to know: don't have match ids? Run the FotMob Matches Scraper (by date) or the FotMob League Scraper (a whole season of fixtures) first — both emit the
matchIds you feed straight in here.
Why this Actor
- The whole match in one record. Score, lineups, per-player stats, events, the team-stat comparison, and the match info box come back together — not scattered across a dozen requests.
- Per-player depth. Each player carries their rating, minutes, goals/assists, shots, xG/xA, passing accuracy, duels, defensive actions, and (for keepers) saves and goals conceded — flattened into a flat, analysis-ready dict.
- A clean events timeline. Goals, cards, and substitutions as a single ordered
eventsarray with minute, player, and running score — not buried inside player objects (a known bug in naïve scrapers, fixed here). - Pick exactly what you need. Toggle player stats, events, lineups, team stats, and head-to-head independently to control item size and cost.
- Robust two-tier fetch. Tries FotMob's embedded page data first (no auth), and falls back to the signed API — automatically, and only trusting the page when its match id matches what you asked for.
- Works globally, no login. No FotMob account, no per-region setup. Apify Proxy (datacenter by default) handles the requests for you.
- You never pay for failures. A match that can't be parsed or fetched is reported in the run summary — not written to your dataset and not billed.
- Clean, consistent output. Integer ids, parsed scores, ISO timestamps, and a stable schema across every league and match.
Problems this Actor solves
| If you are… | Your problem | How this Actor solves it |
|---|---|---|
| A football data / analytics builder | Per-player and team stats live in messy nested payloads behind request signing | One run returns a flat, normalized record per match — players, team stats, events |
| A model / prediction developer | You need rich match features (xG, shots, duels, ratings) at scale | Feed a list of match ids; pull every stat in a stable schema, history included |
| A fantasy / scouting tool builder | Tracking individual performances across matches is manual | Per-player ratings and stats in every record — filter and aggregate downstream |
| A content creator / journalist | Compiling lineups, timelines, and stat comparisons is slow | Lineups, the event timeline, and the head-to-head stat table, export-ready |
| An app / chatbot / agent developer | You want deep match data without building and maintaining a scraper | Pay per match on demand; toggle off sections you don't need to cut size and cost |
What data you get
Each match becomes one dataset record. Top-level fields are always present; the larger sections are optional (toggled by input):
| Field | Description |
|---|---|
matchId | FotMob's stable numeric match id (the record's unique id). Integer |
matchName | FotMob's match label (e.g. Aston Villa-vs-Manchester United_…) |
matchUrl | Absolute FotMob match URL |
leagueId / leagueName | Competition id and name |
round / roundName | Match round / matchday |
countryCode | FIFA country code (e.g. ENG) |
matchTimeUtc | Kickoff time in UTC (ISO 8601) |
started / finished | Match status booleans |
homeTeam / awayTeam | { id, name, score } per side |
tournament | Tournament / stage label, when present |
venue | Stadium name |
referee | Match referee |
attendance | Reported attendance |
playerOfTheMatch | { playerId, name, teamName }, when awarded |
teamStats | Optional: head-to-head stat comparison — see below |
events | Optional: goal/card/substitution timeline — see below |
lineups | Optional: both teams' formations, starters, subs, coach — see below |
playerStats | Optional: per-player stats and ratings — see below |
h2h | Optional: previous meetings between the two teams |
source | Always fotmob-match-details-scraper |
scrapedAt | ISO 8601 timestamp of the run |
rawData | Optional: the full raw FotMob match payload, when Include raw data is on |
teamStats[] — the head-to-head comparison, grouped (Top stats, Shots,
Expected goals (xG), Passes, Defence, Duels, Discipline): each entry is
{ group, title, key, home, away }. Values are numbers or "value (pct%)"
strings, matching how FotMob renders them.
events[] — one ordered entry per goal/card/substitution:
{ type, minute, minuteLabel, isHome, playerId, playerName, homeScore, awayScore },
plus card for cards, goalType/assist for goals, and playersInvolved for
substitutions.
lineups — { home, away }; each side is
{ teamId, teamName, formation, coach, starters[], subs[] }, and each player is
{ playerId, name, shirtNumber, position, rating }.
playerStats[] — one entry per player who featured, with identity
(playerId, name, teamId, teamName, shirtNumber, position,
isGoalkeeper) plus a flat set of that player's match stats — e.g.
rating_title, minutes_played, goals, assists, expected_goals,
expected_assists, total_shots, accurate_passes ("36/42 (85.7%)"),
chances_created, touches, duel_won, clearances, and (for keepers) saves,
goals_conceded. Available stats vary by player and competition.
Example output
Aston Villa 0–0 Manchester United — heavily trimmed (teamStats, events,
lineups, and playerStats are much longer in a real record):
{"matchId": 4506324,"matchName": "Aston Villa-vs-Manchester United_Sun, Oct 6, 2024, 13:00 UTC","matchUrl": "https://www.fotmob.com/match/4506324","leagueId": 47,"leagueName": "Premier League","round": "7","countryCode": "ENG","matchTimeUtc": "2024-10-06T13:00:00.000Z","started": true,"finished": true,"homeTeam": { "id": 10252, "name": "Aston Villa", "score": 0 },"awayTeam": { "id": 10260, "name": "Manchester United", "score": 0 },"venue": "Villa Park","referee": "Robert Jones","attendance": 42682,"playerOfTheMatch": { "playerId": 268375, "name": "Emiliano Martinez", "teamName": "Aston Villa" },"teamStats": [{ "group": "Top stats", "title": "Ball possession", "key": "BallPossesion", "home": 54, "away": 46 },{ "group": "Top stats", "title": "Expected goals (xG)", "key": "expected_goals", "home": "0.50", "away": "0.56" },{ "group": "Top stats", "title": "Accurate passes", "key": "accurate_passes", "home": "345 (83%)", "away": "302 (82%)" }// … more, grouped by Shots / xG / Passes / Defence / Duels / Discipline],"events": [{ "type": "Card", "minute": 3, "minuteLabel": 3, "isHome": false, "playerId": 157723, "playerName": "Christian Eriksen", "card": "Yellow" },{ "type": "Substitution", "minute": 12, "isHome": true, "playersInvolved": ["Diego Carlos", "Ezri Konsa"] }// … goals carry goalType + assist],"lineups": {"home": { "teamId": 10252, "teamName": "Aston Villa", "formation": "4-4-1-1", "coach": "Unai Emery","starters": [ { "playerId": 268375, "name": "Emiliano Martinez", "shirtNumber": "23" } /* … */ ], "subs": [ /* … */ ] },"away": { "teamId": 10260, "teamName": "Manchester United", "formation": "4-2-3-1", "coach": "Erik ten Hag","starters": [ /* … */ ], "subs": [ /* … */ ] }},"playerStats": [{"playerId": 268375, "name": "Emiliano Martinez", "teamId": 10252, "teamName": "Aston Villa","shirtNumber": "23", "isGoalkeeper": true,"rating_title": 8.36, "minutes_played": 90, "saves": 4, "goals_conceded": 0,"accurate_passes": "24/32 (75.0%)", "touches": 40}// … one entry per player who featured],"source": "fotmob-match-details-scraper","scrapedAt": "2026-06-18T11:11:32+00:00"}
A match id that can't be parsed, or a match that won't load, is not written to
the dataset (and never billed). It is listed in the run's SUMMARY record in the
key-value store —
{ "failures": [ { "input": "…", "matchId": …, "error": "…" } ] } — and the run's
status message tells you at a glance how many matches succeeded.
How to use it (60 seconds)
- Click Try for free / Start.
- Add one or more Match ids or URLs (one per line) — e.g.
4506324, or a full match URL likehttps://www.fotmob.com/match/4506324. (Don't have ids? Run the FotMob Matches Scraper or FotMob League Scraper first — both emitmatchIds.) - Toggle the sections you want: player stats, events, lineups, team stats (all on by default), head-to-head (off by default), and optionally raw data.
- Keep the Apify Proxy enabled (datacenter is enough — the default).
- Click Save & Start. Download results as JSON, CSV, Excel, or via API from the Dataset tab; check Key-value store → SUMMARY for run totals and any failed lookups.
Input reference
| Field | Type | Default | Description |
|---|---|---|---|
| Match ids or URLs | list | ["4506324"] | One FotMob match id or match URL per line. Numeric ids, /match/<id> URLs, and …#<id> URLs all work. |
| Include player stats | boolean | true | Per-player statistics and ratings (for started matches). |
| Include events timeline | boolean | true | The goal / card / substitution timeline. |
| Include lineups | boolean | true | Both teams' formations, starters, subs, and coach. |
| Include team stats | boolean | true | The head-to-head team-stat comparison (possession, shots, xG…). |
| Include head-to-head history | boolean | false | Previous meetings between the two teams. Increases item size. |
| Include raw data | boolean | false | Adds the full raw FotMob match payload under rawData. Significantly increases item size. |
| Proxy configuration | object | Apify Proxy (datacenter) | Routes requests through Apify Proxy. Datacenter is enough; switch to Residential only for very large jobs. |
| Max concurrency | integer | 5 | Parallel requests (1–20). Kept moderate to be respectful. |
| Delay between requests | integer | 1 | Politeness delay in seconds before each request (0–10). |
| Max items | integer | 0 | Stop after producing this many records (0 = no limit). |
Pricing — what a run costs
This Actor uses transparent pay-per-event pricing with a built-in volume discount: a small Actor-start fee, a fixed price per successful match record for the first 10,000 results of a run, and a cheaper rate for every result beyond that. No subscription, no minimums, and failed lookups are never charged. The exact per-result rate is shown on the Actor's Pricing tab.
- One billed record per match. Failed lookups bill nothing.
- Failed lookups are free. Unparseable ids and matches that won't load are reported in the summary, never billed.
- Bigger runs cost less per item. The discount tier resets per run, so one large run is cheaper than the same job split into many small ones.
- Trim what you don't need. Toggle off sections (e.g. raw data, head-to-head) to keep items small.
- Try it free: an Apify free account includes $5 of monthly platform credit — enough to try the Actor before paying anything.
- Stay in control: set Max items and Apify's maximum charge per run; the Actor stops gracefully at your cap, keeping everything already scraped.
Compared to the alternatives
| This Actor | Build your own scraper | Manual checking | |
|---|---|---|---|
| Score + lineups + per-player stats + events in one record | Yes | You maintain it | Impractical |
| Team-stat comparison (xG, shots, duels…) | Yes | You parse it | Read off the page |
| Clean event timeline (no dropped assists) | Yes | Easy to get wrong | – |
| Handles FotMob request signing & fallback | Built in | You reverse-engineer it | – |
| Toggle sections to control size/cost | Yes | You build it | – |
| Never billed for failures | Yes | – | – |
| Export JSON / CSV / Excel / API | Yes, built-in | DIY | Copy-paste |
| Setup time | ~60 seconds | Days; breaks on site changes | Hours per match |
A family of FotMob Actors
This Actor is the deep-dive endpoint of a set that fit together:
- FotMob Leagues List Scraper — discover every league/competition and its id.
- FotMob League Scraper — standings, fixtures, results, and season top players;
emits a season's
matchIds. - FotMob Matches Scraper — every match for a date or range; emits
matchIds. - FotMob Match Details Scraper (this Actor) — pass those
matchIds to get lineups, events, team stats, and per-player match stats.
Typical flow: discover matches with the Matches or League Scraper → take the
matchIds → run this Actor for the deep per-match data.
Integrate the data
- Exports: JSON, CSV, Excel, XML from the Dataset tab — or fetch
programmatically:
GET https://api.apify.com/v2/datasets/{datasetId}/items?format=json
- Run on a schedule: use Apify Schedules to expand each day's finished matches into details, and webhooks to push finished runs into your pipeline (Sheets, Slack, your backend).
- Chain from discovery: read
matchIds from the FotMob Matches Scraper or FotMob League Scraper and pass them straight in here. - From code: call the Actor with the Apify API or SDKs (Python / JavaScript) and read the dataset when the run finishes.
- Run summary: every run writes a
SUMMARYrecord (key-value store) with totals, successes, failures, and billing counts — ideal for monitoring automated pipelines.
FAQ
Do I need a FotMob account or login? No. There is no account or login required.
Where do I get match ids?
From the FotMob Matches Scraper (by date) or the FotMob League Scraper (a
whole season of fixtures) — both emit matchIds. You can also paste a full FotMob
match URL here; the Actor extracts the id for you.
Why is playerStats missing on some matches?
Per-player stats are only emitted for matches that have started. Upcoming matches
return lineups (when announced) but no player stats.
Are player ratings included?
Yes — each player's rating_title is in playerStats. (Ratings in the lineups
section can be null until FotMob populates them post-match; the authoritative
rating is in playerStats.)
Can I make the records smaller? Yes. Turn off any of player stats, events, lineups, team stats, head-to-head, or raw data to keep only what you need.
Do I need a proxy? Apify Proxy is pre-selected (datacenter) and is enough for most runs; switch to Residential only if you hit blocks on very large jobs.
How fresh is the data? Each run fetches live data, so you get exactly what FotMob shows at that moment — including in-progress matches.
What formats can I export? JSON, CSV, Excel, XML — from the Console or via the Apify API.
Disclaimer
This Actor is intended for personal and research use. You are responsible for ensuring your use complies with FotMob's terms and applicable law. Please scrape responsibly — keep concurrency moderate and delays reasonable. This project is not affiliated with, endorsed by, or sponsored by FotMob.