Football Results Scraper - Goals, Cards & Stats, All Leagues
Pricing
from $3.65 / 1,000 match returneds
Football Results Scraper - Goals, Cards & Stats, All Leagues
For football bettors, fantasy players and data teams: results from every league on Flashscore with goal scorers, assists, cards, substitutions, half-time score, round and stats incl. xG. 3,260 of 3,260 matches matched Flashscore's page in a 3-day check. Monitoring returns only matches that changed.
Pricing
from $3.65 / 1,000 match returneds
Rating
0.0
(0)
Developer
NeverEmpty
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
For football bettors, fantasy players and data teams: every match Flashscore lists, across all countries and leagues, with teams, league, round, score, half-time score, winner, red cards and status, plus goal scorers with assists and minute, cards, substitutions, referee, attendance and match statistics including xG. In a check on 2026-09-21, 3,260 of 3,260 matches over 3 days matched Flashscore's own page field by field. Ask by date, league name or team name - no match ids to look up - and turn on monitoring so a schedule receives only the matches that finished or whose score changed.
Export as JSON, CSV or Excel.
What you get
One row per match, for any day from 7 days back to 7 days ahead:
- League: country or region, league name, Flashscore's header (
ENGLAND: Premier League), league id and page, and the round (Round 5,Quarter-finals), read from the match page because Flashscore's daily feed does not carry it. - Teams: home and away as Flashscore shows them, with Flashscore team id, slug and short code.
- Score: the score, half-time score, 90-minute score, score after extra time, penalty shoot-out score, winner (
home,awayordraw) and how it was decided (regular-time,extra-time,penalties), red cards per team. - Status: scheduled, live (with the period and the minute), finished, postponed, cancelled, interrupted, abandoned, awarded and more, with Flashscore's own status text.
- Events (matches that have started): goals with scorer, assist, minute, penalty or own goal and the score after it; yellow, second-yellow and red cards with the reason; substitutions; missed penalties; half scores; referee, stadium, city, attendance and capacity.
- Statistics (matches that have started): possession, shots, shots on target, corners, fouls, offsides, yellow cards and xG as columns, and every statistic Flashscore shows (passes, big chances, xGOT, tackles...) for the match and each half in
statistics.
Between 2026-09-14 and 2026-09-20 Flashscore's daily football feed carried 171 to 1,780 matches a day (weekend days the most).
How it matches Flashscore's page
The rows come from the same feeds Flashscore's website reads, assembled the way the page assembles them:
- The daily feed can be minutes old. It is served from a cache, so the page applies Flashscore's recent-changes feed on top right after loading. This Actor does the same, and every row says whether that step worked in
liveUpdatesApplied. When the cached copy that answered is older than two minutes the Actor asks again (up to twice) and keeps the freshest;feedAgeSecondssays how old it was. - Each day's feed also carries matches that belong to the day before or after. Flashscore's page does not show them on that day, and neither does this Actor: a match is returned under the day it starts on in your time zone.
- After a penalty shoot-out Flashscore's feed adds one goal to the winner. The page shows the real score and the shoot-out in brackets, and so does this Actor:
homeScore/awayScoreare the goals after extra time, the shoot-out is inpenaltiesHomeScore/penaltiesAwayScore. - The half-time score is not in the daily feed; it is the 90-minute score minus the second-half score, which matched the half scores of Flashscore's match pages on every match checked.
The check behind the numbers above: Flashscore's football page was opened in a browser on 2026-09-21 for three days with every collapsed league expanded, and at the same moment the daily and recent-changes feeds were read. Every match on the page (3,260) was compared on team names, score, penalty shoot-out score, red cards, status text, the live minute, the start time and the day it is listed on: 3,260 of 3,260 matched.
Input
| Field | What it does |
|---|---|
days | Days to read: today, yesterday, tomorrow, a number from -7 to 7, or YYYY-MM-DD. Empty = today. Days outside Flashscore's 15-day window are refused before anything is requested. |
utcOffsetHours | Your time zone as hours from UTC (0 = UTC). Decides where a day starts, as on Flashscore in that time zone. startTime is always UTC. |
countries | Keep only these countries or regions as Flashscore names them (England, Spain, Europe, World). Whole name, case-insensitive. |
leagues | Keep a match if its league matches one of these: Flashscore's header or part of it (england: premier league, champions league), the league path (england/premier-league) or a league URL. premier league alone also keeps other countries' Premier Leagues. |
teams | Keep a match if one of these appears in the home or away team name or slug (partial, case-insensitive). |
matchStatuses | live, finished, scheduled, other (postponed, cancelled, interrupted...). Empty = all. |
includeEvents | On (default) = one extra request per returned match that has started, for goals, cards, substitutions, referee and attendance. |
includeStatistics | On (default) = one extra request per returned match that has started, for match statistics. |
includeRound | On (default) = one small extra request per returned match to read the round from its page (only the first 32 KB are read). Off = faster, round is null. |
maxMatches | Maximum rows to return (default 200, up to 3,000). Not used in monitoring mode. |
monitoringMode | Return only matches that changed since the row last returned for them. Needs at least one of countries, leagues or teams, unless monitorEveryLeague is on. |
monitorEveryLeague | Allow monitoring with no country, league or team filter. Off (default) = such a run is refused with a free row, because its first run would return and charge every match of the day. |
changeDetail | In monitoring mode: score (default: a goal, a red card, extra-time or shoot-out score, or a change of status such as kick-off or full time; half time and the minute do not count) or finished (each match once, when it reaches a final state: finished, walkover, awarded, cancelled or abandoned). |
resetMonitoringState | Forget the remembered rows for this filter set, so everything counts as new. |
useProxy | On (default) = if Flashscore answers 401, 403, 429 or 503, retry through an Apify proxy. |
Example: yesterday's and today's results from the Premier League and LaLiga, in London summer time.
{"days": ["yesterday", "today"],"utcOffsetHours": 1,"leagues": ["england: premier league", "spain: laliga"],"matchStatuses": ["finished"]}
Output
A finished match returned by a monitoring run (change and the previous... fields appear only in monitoring mode; statistics is cut to 3 of its 101 entries here):
{"source": "flashscore.com","status": "ok","matchId": "fZCq6HE7","matchUrl": "https://www.flashscore.com/match/fZCq6HE7/","date": "2026-09-20","utcOffsetHours": 0,"startTime": "2026-09-20T13:00:00.000Z","country": "England","league": "Premier League","leagueHeader": "ENGLAND: Premier League","leagueId": "dYlOSQOD","leagueUrl": "https://www.flashscore.com/football/england/premier-league/","round": "Round 5","matchStatus": "finished","statusText": "Finished","statusCode": 3,"isLive": false,"isFinished": true,"livePeriod": null,"liveMinute": null,"statusChangedAt": "2026-09-20T14:57:59.000Z","homeTeam": "Manchester City","homeTeamId": "Wtn9Stg0","homeTeamSlug": "manchester-city","homeTeamShort": "MCI","awayTeam": "Sunderland","awayTeamId": "WSzc94ws","awayTeamSlug": "sunderland","awayTeamShort": "SUN","homeScore": 5,"awayScore": 3,"scoreText": "5-3","winner": "home","winnerTeam": "Manchester City","decidedBy": "regular-time","halfTimeHomeScore": 3,"halfTimeAwayScore": 2,"regularTimeHomeScore": 5,"regularTimeAwayScore": 3,"extraTimeHomeScore": null,"extraTimeAwayScore": null,"penaltiesHomeScore": null,"penaltiesAwayScore": null,"homeRedCards": 0,"awayRedCards": 0,"info": null,"scrapedAt": "2026-09-21T15:00:00.000Z","liveUpdatesApplied": true,"feedAgeSeconds": null,"change": "status-changed","previousMatchStatus": "live","previousScoreText": "4-3","previousHomeScore": 4,"previousAwayScore": 3,"previousReturnedAt": "2026-09-20T17:08:00.000Z","eventsStatus": "ok","goals": [{"period": "1st Half","minute": "9","minuteValue": 9,"team": "home","player": "Fernandez E.","playerId": "nZnbEVWP","type": "goal","assist": null,"assistId": null,"homeScoreAfter": 1,"awayScoreAfter": 0},{"period": "1st Half","minute": "12","minuteValue": 12,"team": "away","player": "Brobbey B.","playerId": "pfAvgQUT","type": "goal","assist": "Le Fee E.","assistId": "hC5yfF2A","homeScoreAfter": 1,"awayScoreAfter": 1},{"period": "1st Half","minute": "29","minuteValue": 29,"team": "home","player": "Cherki R.","playerId": "vm0eu2V3","type": "goal","assist": "Semenyo A.","assistId": "r1Gz1yPk","homeScoreAfter": 2,"awayScoreAfter": 1},{"period": "1st Half","minute": "33","minuteValue": 33,"team": "away","player": "Brobbey B.","playerId": "pfAvgQUT","type": "goal","assist": "Meunier T.","assistId": "WUyrShAL","homeScoreAfter": 2,"awayScoreAfter": 2},{"period": "1st Half","minute": "43","minuteValue": 43,"team": "home","player": "Semenyo A.","playerId": "r1Gz1yPk","type": "goal","assist": "Guehi M.","assistId": "KEeklutO","homeScoreAfter": 3,"awayScoreAfter": 2},{"period": "2nd Half","minute": "57","minuteValue": 57,"team": "home","player": "Semenyo A.","playerId": "r1Gz1yPk","type": "goal","assist": null,"assistId": null,"homeScoreAfter": 4,"awayScoreAfter": 2},{"period": "2nd Half","minute": "59","minuteValue": 59,"team": "away","player": "Brobbey B.","playerId": "pfAvgQUT","type": "goal","assist": "Angulo N.","assistId": "GtWYwr5H","homeScoreAfter": 4,"awayScoreAfter": 3},{"period": "2nd Half","minute": "81","minuteValue": 81,"team": "home","player": "Haaland E.","playerId": "UmV9iQmE","type": "goal","assist": "Gvardiol J.","assistId": "86K1f1fd","homeScoreAfter": 5,"awayScoreAfter": 3}],"goalsText": "9' Fernandez E. [home]; 12' Brobbey B. [away]; 29' Cherki R. [home]; 33' Brobbey B. [away]; 43' Semenyo A. [home]; 57' Semenyo A. [home]; 59' Brobbey B. [away]; 81' Haaland E. [home]","goalsListed": 8,"goalsComplete": true,"cards": [{"period": "1st Half","minute": "8","minuteValue": 8,"team": "away","player": "Methalie D.","playerId": "v71VNtNg","card": "yellow","reason": "Roughing","onBench": false}],"substitutions": [{"period": "2nd Half","minute": "60","minuteValue": 60,"team": "away","playerIn": "Fofana M.","playerInId": "6N65iDOI","playerOut": "Angulo N.","playerOutId": "GtWYwr5H"},{"period": "2nd Half","minute": "68","minuteValue": 68,"team": "away","playerIn": "Isidor W.","playerInId": "veOg2tx3","playerOut": "Sadiki N.","playerOutId": "UJnCIUV6"},{"period": "2nd Half","minute": "75","minuteValue": 75,"team": "home","playerIn": "Doku J.","playerInId": "lMHcYK4f","playerOut": "Ndiaye I.","playerOutId": "Im0c6Oy7"},{"period": "2nd Half","minute": "79","minuteValue": 79,"team": "away","playerIn": "Hume T.","playerInId": "CfLIw4XG","playerOut": "Meunier T.","playerOutId": "WUyrShAL"},{"period": "2nd Half","minute": "85","minuteValue": 85,"team": "home","playerIn": "O'Reilly N.","playerInId": "xOrYaNWc","playerOut": "Cherki R.","playerOutId": "vm0eu2V3"}],"missedPenalties": [],"periods": [{"period": "1st Half","homeScore": 3,"awayScore": 2},{"period": "2nd Half","homeScore": 2,"awayScore": 1}],"referee": "Jones R.","venue": "Etihad Stadium","city": "Manchester","attendance": 60312,"venueCapacity": 61038,"statisticsStatus": "ok","statistics": [{"period": "Match","group": "Top stats","name": "Expected goals (xG)","home": "2.81","away": "3.57"},{"period": "Match","group": "Top stats","name": "Ball possession","home": "55%","away": "45%"},{"period": "Match","group": "Top stats","name": "Total shots","home": "16","away": "17"}],"homePossession": 55,"awayPossession": 45,"homeShots": 16,"awayShots": 17,"homeShotsOnTarget": 6,"awayShotsOnTarget": 9,"homeCorners": 6,"awayCorners": 5,"homeXg": 2.81,"awayXg": 3.57,"homeFouls": 14,"awayFouls": 14,"homeYellowCards": 0,"awayYellowCards": 1,"homeOffsides": 0,"awayOffsides": 0,"roundStatus": "ok"}
Notes on the columns:
homeScore/awayScoreare null before kick-off. For a match decided on penalties they are the goals after extra time; the shoot-out is inpenaltiesHomeScore/penaltiesAwayScore.regularTimeHomeScoreis the score after 90 minutes,extraTimeHomeScoreafter extra time (null when there was none).halfTimeHomeScore/halfTimeAwayScoreare filled once the first half is over.homeRedCards/awayRedCardscount red cards (including second yellows) as Flashscore shows them on the list; null before kick-off.livePeriodisfirst-half,half-time,second-half,extra-time,breakorpenalties.liveMinuteis worked out the way Flashscore's page does it (minutes since the period started,45+2/90+3in added time) and can be a minute off the page.statusCodeis Flashscore's own status number;statusTextis Flashscore's text for it;matchStatusis one ofscheduled,live,finished,walkover,awarded,cancelled,postponed,interrupted,abandoned,delayed,awaiting-updates,to-finish(orended/unknownfor a status number Flashscore adds later).goals[].teamis the side the goal counts for; an own goal (type: "own-goal") is credited to the other team, soplayerplays for the opposite side.goals[].typeisgoal,penaltyorown-goal. Penalty shoot-out kicks are not listed as goals.cards[].cardisyellow,second-yelloworred;onBenchis true for a card shown to someone not on the pitch.eventsStatus:ok,no-incidents-listed(Flashscore lists only the half scores for this match, common in lower leagues),not-available(Flashscore returned no events at all for this match),not-started,unreadableornot-requested. Lower leagues often list a goal without the scorer's name (playeris null, shown as?ingoalsText).goalsListedis how many goals have a named scorer;goalsCompleteis true only when every goal scored has a named scorer.statisticsStatus:ok,not-available(Flashscore has no statistics for this match),not-started,unreadableornot-requested. Thehome.../away...statistic columns are numbers (possession in percent);statisticskeeps Flashscore's text such as85% (406/475). xG is only there for leagues where Flashscore shows it.roundStatus:ok,not-shown(the match page shows no round),unreadableornot-requested.infois Flashscore's note on the match, such asFirst leg result: 2-1. Aggregate: 3-1.change(monitoring):"first-check"(not returned before for this filter set),"status-changed"or"score-changed".- Odds, TV listings, line-ups and commentary text are not included.
Rows that are not charged
When something is not returned, a row says why. These rows have no matchId and cost nothing:
status | Meaning |
|---|---|
no-results | Flashscore lists no matches for the day(s) asked for. |
no-filter-match | Matches were read, none fit your filters. |
no-change | Monitoring: no match changed since its last returned row. |
not-returned | More matches fit than maxMatches; the row says how many. |
budget-reached | The run hit its maximum total charge; the row says how many matches were not returned. |
day-out-of-range | Flashscore did not return the day (outside its 7-back / 7-ahead window). |
blocked | Flashscore refused the request even after retrying. |
unreadable | Flashscore's answer could not be read. Nothing is guessed. |
invalid-input | The input could not be used; nothing was requested. |
Monitoring
Run the Actor on a schedule with monitoringMode on. The first run returns every match that fits your filters (with changeDetail: "finished", every match that has already ended). Later runs compare each match with the row last returned for it and return only the ones that changed, with the previous score and status next to the new ones, and with fresh goals, cards and statistics.
- Every match compared is a check, also the first time a match is seen. A match that was already returned in a final state (finished, walkover, awarded, cancelled or abandoned) and has not changed is not charged a check.
- A match is listed on the day it starts. For a schedule that runs across midnight, put
["yesterday", "today"]indays, or a late match that ends after midnight drops off the list before its result is returned. - With
matchStatuses: ["live"]a match leaves your filter when it ends, so its final result is not returned. Keepfinishedin the filter to receive results. - A match that looks older than the row already returned for it (an older cached copy of Flashscore's feed, or a goal Flashscore took back) is not returned as a change.
- Rows are remembered per filter set (
countries,leagues,teams,matchStatuses,changeDetail) for 10 days after the match starts, so two schedules with different filters do not affect each other. maxMatchesis not used in monitoring mode, so no match is left out behind the limit. For the same reason monitoring needs at least one ofcountries,leaguesorteams: with no filter, the first run would return every match of the day (up to about 1,800). Turn onmonitorEveryLeagueif that is what you want.- A row is remembered only after it was delivered and charged. If a run hits its maximum total charge, the matches it could not return are not remembered as returned, so they still count as changed when they are compared again.
- Do not put the same filter set in two schedules that can run at the same time: the remembered rows live in a key-value store without atomic updates, so this cannot be fully prevented.
Pricing
Pay per event, no start fee:
- $5.00 per 1,000 match rows, charged only for rows with
status: "ok". Goals, cards, statistics and the round are included in the row price. - $0.30 per 1,000 match checks in monitoring mode.
Example: 20 matches you follow, checked every 5 minutes for 3 hours, is 720 checks, which is $0.22, plus $0.005 for each change row (a goal, a red card, kick-off or full time). Checking every match of a busy Saturday (about 1,800) every 5 minutes for 12 hours would be 259,200 checks, so use filters for frequent schedules.
Notes
- Unofficial. Public data only. Not affiliated with Flashscore or Livesport. Data is what Flashscore shows publicly and can change or be corrected by Flashscore.
- Only Flashscore's football feeds and match pages that its robots.txt allows are read; standings, draws and news are not.
- Requests are spaced out: a 0.4 s pause before each request, and at most 3 matches' details in flight at once. With goals, statistics and the round on, a run takes about 0.75 s per match row (1,329 rows took 16 minutes on 2026-09-21); the log reports progress every 100 rows.