ParseForge Scrapers

Football-Data.co.uk Scraper - Results, Stats & Odds

parseforge/football-data-couk-scraper

Developer toolsOther

Scrape 240,000+ football matches from Football-Data.co.uk: 38 competitions, results, half-time scores, shots, cards, corners, referees, xG, and 1X2 / over-under / Asian handicap odds from 22 bookmakers.

Run this scraper See the API call
Total users
2
Monthly active
1
Total runs
27
Bookmarked
0
Rating
Not rated yet
Last modified
28 hours ago

Overview

ParseForge

Football-Data.co.uk Scraper - Results, Stats & Odds

Every match Football-Data.co.uk publishes, normalised into one schema. 304,000+ played matches across 38 competitions and 34 seasons, with full-time and half-time scores, shots, corners, cards, referees, expected goals, and 1X2, over/under and Asian handicap prices from 22 bookmakers. No API key, no login, no proxy. Export to CSV, JSON, Excel, or XML.

It is the football API alternative for anyone who needs history rather than live scores: one soccer dataset covering three decades, queryable by league, season, team, referee, scoreline, or price. Football-Data.co.uk is the reference free archive for football betting research, but it ships as 726 separate CSV files across which 233 distinct column names have appeared: HomeTeam is HT in the old Greek files, FTHG is HG in the extra leagues, 15 files are Windows-1252 rather than UTF-8, and a bookmaker that quoted every match in 2007 has no column at all in 2021. This Actor reads all of it, resolves every alias, and returns one stable row per match.

Who uses it What they pull
Bettors and traders Closing lines, market margin, and pre-match to closing drift
Quants and modellers Decades of results plus odds, ready to back-test
Data scientists A labelled corpus with the market's own probability attached
Sports journalists Head-to-head records, streaks, and league tables on demand
App and site builders Fixtures with opening prices, refreshed on a schedule

What it does

The Actor downloads the season files you select, parses them, and writes one row per match. A row can carry:

  • โšฝ The match: competition, country, tier, season, date, kick-off time, both teams, full-time and half-time score.
  • ๐Ÿ“Š Every result flag already computed: total goals, goal difference, both-teams-scored, over 0.5/1.5/2.5/3.5, clean sheets, second-half goals, comeback detection, and league points for each side.
  • ๐Ÿฅ… Match statistics (opt-in): referee, shots, shots on target, corners, fouls, free kicks conceded, offsides, woodwork, yellows, reds, booking points, attendance, expected goals, plus shot accuracy and conversion rate.
  • ๐Ÿ’ท Bookmaker odds (opt-in): 1X2, over/under 2.5 and Asian handicap, pre-match and closing, from up to 22 books including Bet365, Pinnacle, William Hill, bwin, BetVictor, Ladbrokes, Betfred, BetMGM, Coral, Paddy Power, Sky Bet, 1XBet and the Betfair Exchange.
  • ๐Ÿ“ˆ Market consensus (opt-in): best and average price across the whole market for each market, and how many books that average was built from.
  • ๐Ÿงฎ Betting analytics (opt-in): implied and margin-free probabilities, overround, fair odds, favourite and underdog, best available price, expected-value edge, Kelly fraction, steamer/drifter flags, closing line value, and the settled profit or loss of a one-unit bet on each outcome.
  • ๐Ÿ” Head-to-head and form (opt-in): the two sides' entire meeting history in that competition, and both teams' rolling record going into the match.
  • ๐Ÿ† League tables (opt-in): a full table per competition-season, with split home and away records.

What you can do with football data

๐Ÿ“‰ Back-test a betting model.

Pull twenty seasons with closing odds and betting analytics on. Every row already carries the fair probability, the margin, and the P/L of a one-unit bet, so a strategy test is a groupby away.

๐ŸŽฏ Measure closing line value.

Turn on closing odds and analytics, and read clvWinnerPercent per match to see whether the price you would have taken beat the close.

๐Ÿง  Train a match-outcome model.

Combine results, shots, expected goals and team form into a feature table without joining four sources by hand, the form block is computed as of kick-off, so there is no leakage from the future.

๐Ÿ”Ž Find market inefficiencies.

Filter on bookmaker margin, favourite side, or steamers over a threshold, and look at how often the drift was right.

๐Ÿ“… Track this week's fixtures.

Switch to the fixtures dataset and schedule it: upcoming matches with the current opening prices from every book that has quoted them.

Why choose this scraper

What you get
Nothing to authenticate No API key, no account, no cookie. The source is public static hosting.
No proxy cost Measured HTTP 200 on every surface with a bare request. There is no proxy line on your bill.
38 competitions in one run 22 European divisions, the biggest back to 1993/94, plus 16 more from Argentina to Japan.
Every legacy column resolved Old alias names, retired bookmakers, and the 15 Windows-1252 files all land in the same schema.
Opt-in extras, off by default Ten separate blocks, each its own checkbox. Leave them off and you are never billed for them.
Filters cut before billing Filters run on the complete match, so you can filter on shots or margin without buying those columns.
Pick by country One checkbox brings in every tier that country has, and a per-competition cap keeps one league from eating the run.
Signals already computed Fair probabilities, margin, CLV, form and head-to-head, ready to sort.
Odds in your format Decimal, fractional on the traditional UK ladder, or American.

How it compares

Be clear about the trade-off before you pick this one.

The source CSVs are free. Football-Data.co.uk hands anyone 726 files at no cost, and if you want one season of one league you should just download it. What you are paying for here is the other 725 files: the alias resolution, the encoding fallback, the filters, the computed analytics, the head-to-head and form indexes, and a scheduled run that keeps a warehouse table current without you maintaining a parser.

The only other Actor on this source takes four inputs: one league, one season, an odds on/off switch, and a row cap.

Feature ParseForge crawlerbros/football-data-uk-scraper Downloading the CSVs yourself
Leagues per run 38, any number at once One Any, by hand
Seasons per run Any range, 1993/94 onward One Any, by hand
Per-bookmaker odds resolved by name 22 books One on/off switch Raw column names
Closing odds and pre-match drift Yes No Raw columns only
Computed probabilities, margin, CLV Yes No No
Head-to-head and pre-match form Yes No No
League tables Yes No No
Legacy alias columns resolved Yes No No
Upcoming fixtures with prices Yes No Yes, separate file
Filters 42 None None
Price per 1,000 matches $3.00 Per dataset item Free

If your job is "download E0 for 2024/25 once", the free CSV wins and you should take it.

What a match looks like

Every match returns as one JSON row: 52 base columns plus one nested object per block you enabled. Here is a real record from a run with every block on, trimmed to four bookmakers:

{
  "matchId": "300fd497fd08e094",
  "recordType": "match",
  "status": "played",
  "source": "football-data.co.uk",
  "sourceUrl": "https://www.football-data.co.uk/mmz4281/2526/E0.csv",
  "competitionId": "E0",
  "competitionName": "Premier League",
  "country": "England",
  "countryCode": "GB-ENG",
  "tier": 1,
  "leagueType": "main",
  "season": "2526",
  "seasonLabel": "2025/26",
  "seasonStartYear": 2025,
  "date": "2025-08-15",
  "dateRaw": "15/08/2025",
  "time": "20:00",
  "dayOfWeek": "Friday",
  "isWeekend": false,
  "homeTeam": "Liverpool",
  "awayTeam": "Bournemouth",
  "fullTimeHomeGoals": 4,
  "fullTimeAwayGoals": 2,
  "fullTimeResult": "H",
  "resultLabel": "Home win",
  "scoreline": "4-2",
  "winner": "Liverpool",
  "loser": "Bournemouth",
  "isDraw": false,
  "halfTimeHomeGoals": 1,
  "halfTimeAwayGoals": 0,
  "halfTimeResult": "H",
  "secondHalfHomeGoals": 3,
  "secondHalfAwayGoals": 2,
  "totalGoals": 6,
  "goalDifference": 2,
  "absGoalDifference": 2,
  "bothTeamsScored": true,
  "over05": true, "over15": true, "over25": true, "over35": true, "under25": false,
  "homeCleanSheet": false,
  "awayCleanSheet": false,
  "homeFailedToScore": false,
  "awayFailedToScore": false,
  "isComeback": false,
  "comebackTeam": null,
  "homePoints": 3,
  "awayPoints": 0,
  "stats": {
    "referee": "A Taylor",
    "attendance": null,
    "homeShots": 19,
    "awayShots": 10,
    "homeShotsOnTarget": 10,
    "awayShotsOnTarget": 3,
    "homeShotAccuracy": 0.5263,
    "awayShotAccuracy": 0.3,
    "homeConversionRate": 0.2105,
    "awayConversionRate": 0.2,
    "totalShots": 29,
    "totalShotsOnTarget": 13,
    "homeCorners": 6,
    "awayCorners": 7,
    "totalCorners": 13,
    "homeFouls": 7,
    "awayFouls": 10,
    "homeYellowCards": 1,
    "awayYellowCards": 2,
    "homeRedCards": 0,
    "awayRedCards": 0,
    "totalCards": 3,
    "homeExpectedGoals": null,
    "awayExpectedGoals": null
  },
  "odds1x2": {
    "bet365": {
      "home": 1.3,
      "draw": 6,
      "away": 8.5
    },
    "pinnacle": {
      "home": 1.28,
      "draw": 6.56,
      "away": 9.07
    },
    "betfairExchange": {
      "home": 1.34,
      "draw": 6.6,
      "away": 9.4
    },
    "bookmakerCount": 9
  },
  "closingOdds": {
    "bet365": {
      "home": 1.29,
      "draw": 6.25,
      "away": 9
    },
    "pinnacle": {
      "home": 1.29,
      "draw": 6.55,
      "away": 9.75
    },
    "bookmakerCount": 9,
    "marketMax": {
      "home": 1.31,
      "draw": 6.6,
      "away": 9.5
    },
    "marketAverage": {
      "home": 1.29,
      "draw": 6.02,
      "away": 8.68
    }
  },
  "overUnder": {
    "prematch": {
      "bet365": {
        "over": 1.36,
        "under": 3.2
      },
      "line": 2.5,
      "marketAverage": {
        "over": 1.35,
        "under": 3.13
      },
      "bookmakerCount": 3
    },
    "closing": {
      "bet365": {
        "over": 1.36,
        "under": 3.2
      },
      "line": 2.5,
      "marketAverage": {
        "over": 1.36,
        "under": 3.05
      },
      "bookmakerCount": 3
    }
  },
  "asianHandicap": {
    "prematch": {
      "bet365": {
        "home": 1.83,
        "away": 2.03,
        "line": null
      },
      "line": -1.5,
      "lineLabel": "Home -1.5",
      "marketAverage": {
        "home": 1.78,
        "away": 1.99
      },
      "bookmakerCount": 3
    },
    "closing": {
      "line": -1.75,
      "lineLabel": "Home -1.75",
      "marketAverage": {
        "home": 1.94,
        "away": 1.76
      },
      "bookmakerCount": 3
    }
  },
  "marketConsensus": {
    "maxHome": 1.34,
    "maxDraw": 6.5,
    "maxAway": 9.5,
    "avgHome": 1.31,
    "avgDraw": 5.96,
    "avgAway": 8.31,
    "maxClosingHome": 1.31,
    "avgClosingHome": 1.29,
    "bookmakersUsed1x2": null
  },
  "analytics": {
    "referenceSource": "market average",
    "referenceIsClosingPrice": false,
    "bookmakersPricing": 9,
    "referenceHomeOdds": 1.31,
    "referenceDrawOdds": 5.96,
    "referenceAwayOdds": 8.31,
    "closingHomeOdds": 1.29,
    "closingDrawOdds": 6.02,
    "closingAwayOdds": 8.68,
    "impliedProbabilityHome": 0.7634,
    "overround": 0.0515,
    "overroundPercent": 5.15,
    "fairProbabilityHome": 0.726,
    "fairProbabilityDraw": 0.1596,
    "fairProbabilityAway": 0.1144,
    "fairOddsHome": 1.377,
    "favourite": "home",
    "favouriteOdds": 1.31,
    "favouriteProbability": 0.726,
    "underdog": "away",
    "underdogOdds": 8.31,
    "favouriteWon": true,
    "underdogWon": false,
    "isUpset": false,
    "winnerOdds": 1.31,
    "profitHome": 0.31,
    "profitDraw": -1,
    "profitAway": -1,
    "profitFavourite": 0.31,
    "bestPriceHome": 1.34,
    "bestValueSide": "away",
    "bestValueEdgePercent": 8.72,
    "bestValueKellyFraction": 0.0103,
    "oddsMovementHomePercent": -1.53,
    "steamerSide": "home",
    "drifterSide": "away",
    "closingOverround": 0.0565,
    "clvWinnerPercent": 1.55
  },
  "headToHead": {
    "meetings": 16,
    "homeTeamWins": 13,
    "draws": 1,
    "awayTeamWins": 2,
    "homeTeamWinRate": 0.8125,
    "averageTotalGoals": 3.63,
    "bothTeamsScoredRate": 0.3125,
    "over25Rate": 0.8125,
    "lastMeetingDate": "2025-02-01",
    "lastMeetingScore": "0-2",
    "lastMeetingWinner": "Liverpool",
    "last5Results": [
      "2024-09-21 Liverpool 3-0 Bournemouth",
      "2025-02-01 Bournemouth 0-2 Liverpool"
    ],
    "homeVenueMeetings": 8,
    "homeVenueWins": 7
  },
  "form": {
    "window": 6,
    "home": {
      "matchesPlayed": 6,
      "wins": 2,
      "draws": 2,
      "losses": 2,
      "points": 8,
      "pointsPerGame": 1.33,
      "goalsFor": 12,
      "goalsAgainst": 10,
      "goalDifference": 2,
      "formString": "WWLDLD",
      "currentStreak": "1D",
      "unbeatenRun": 1,
      "cleanSheets": 1
    },
    "away": {
      "matchesPlayed": 6,
      "wins": 2,
      "draws": 2,
      "losses": 2,
      "points": 8,
      "pointsPerGame": 1.33,
      "goalsFor": 6,
      "goalsAgainst": 6,
      "goalDifference": 0,
      "formString": "DDWLLW",
      "currentStreak": "1W",
      "unbeatenRun": 1,
      "cleanSheets": 2
    }
  },
  "scrapedAt": "2026-08-25T17:23:30.191Z"
}

Field counts with everything on: 52 base columns, 38 statistics, up to 22 bookmakers ร— 3 prices per market, 15 market-consensus columns, 56 analytics columns, 14 head-to-head columns and 27 form columns.

With League tables on, the run also writes recordType: "standing" rows: team, position, played, W/D/L, goals for and against, goal difference, points, points per game, split home and away records, clean sheets, both-teams-scored and over-2.5 counts, and recent form.

What the source actually carries

Coverage is not uniform, and the Actor does not invent columns. Measured across all 726 files:

Data Available from Where
Result, half-time score 1993/94 Every main league
Shots, corners, fouls, cards, referee 2000/01 Main leagues
Attendance, woodwork, offsides, booking points 2000/01 - 2001/02 only England, Scotland, Germany
Bet365 1X2 and over/under 2.5 2002/03 Main leagues
BetBrain market aggregates 2005/06 - 2018/19 Main leagues (retired since)
Pinnacle 2012/13 Main leagues
Extra leagues (closing odds only) 2012 Argentina, Brazil, MLS and 13 more
Free kicks conceded instead of fouls 2017/18 - 2018/19 France 2, Belgium, Greece
Kick-off time, closing odds, market max/average, Asian handicap line 2019/20 Main leagues
Betfair Exchange prices 2024/25 Main leagues
Expected goals (xG) 2026/27 17 of 22 main leagues

Bookmakers come and go: Bet365 prices appear in 544 of the 710 season files, Pinnacle in 308, BetMGM in only 22. The bookmakerCount on each odds block tells you how many actually priced that match.

Configure the run

Pick leagues, pick a season range, tick the blocks you want. The Input tab lists all 64 parameters, 42 of them filters.

One Premier League season, results only:

{ "leagues": ["E0"], "seasonFrom": "2025/26", "seasonTo": "2025/26" }

Twenty seasons of the big five, with odds and analytics, for a back-test:

{
  "leagues": ["E0", "SP1", "I1", "D1", "F1"],
  "seasonFrom": "2005/06", "seasonTo": "2025/26",
  "includeOdds1x2": true,
  "includeClosingOdds": true,
  "includeMarketConsensus": true,
  "includeBettingAnalytics": true
}

Every upset at 6.00 or longer, last two seasons:

{
  "leagues": ["E0", "E1", "E2", "E3"],
  "upsetsOnly": true,
  "upsetMinOdds": 6.0,
  "includeBettingAnalytics": true
}

Matches with a sending off, filtered without buying the statistics columns:

{ "leagues": ["SP1"], "seasonFrom": "2015/16", "minRedCards": 1 }

The 2025/26 Premier League table, plus the matches it was built from:

{ "leagues": ["E0"], "seasonFrom": "2025/26", "seasonTo": "2025/26", "includeStandings": true }

This week's fixtures with the current prices:

{ "leagues": ["E0", "SP1", "I1"], "dataset": "fixtures", "includeOdds1x2": true }

Every Scottish tier, three matches each, only where at least seven books priced the game:

{
  "countries": ["Scotland"],
  "seasonFrom": "2024/25", "seasonTo": "2024/25",
  "matchesPerLeague": 3,
  "minBookmakerCount": 7,
  "includeOdds1x2": true
}

Argentina and MLS, with head-to-head history:

{ "extraLeagues": ["ARG", "USA"], "seasonFrom": "2023", "includeHeadToHead": true }

Pricing

Pay-per-event. You are billed per match row written, plus a small fee for each season file downloaded and a $0.054 run-start fee. Filtered-out matches cost nothing.

Event Price When it fires
Run start $0.054 Once per run
Season file $0.02 Each CSV downloaded for your selection
Match $0.003 Each match row written
Match statistics $0.001 Only with Match statistics on
Pre-match 1X2 odds $0.0015 Only with Pre-match 1X2 odds on
Closing 1X2 odds $0.0015 Only with Closing 1X2 odds on
Over / under odds $0.001 Only with Over / under 2.5 goals on
Asian handicap odds $0.001 Only with Asian handicap odds on
Market max and average $0.001 Only with Market maximum and average on
Betting analytics $0.002 Only with Betting analytics on
Head-to-head history $0.003 Only with Head-to-head history on
Team form $0.002 Only with Team form on
League table row $0.01 Only with League tables on
What you collect Approximate cost
One Premier League season (380 matches) $1.21
The same season with closing odds and analytics $2.54
The same season with every block on $6.53
10,000 matches, results only $30.60

Turning on all nine per-match blocks adds $0.014 per match on top of the $0.003 base. Most runs need one or two of them.

Every block is off by default. A run that leaves them off pays the run-start fee, $0.02 per season file, and $0.003 per match. A block is billed only on the rows where it is actually returned: when the source file has no such column the block is omitted, so a 1996 match with no odds columns fires no odds event.

Free users

Free-plan runs return up to 10 matches as a preview. Upgrade your Apify plan to collect up to 1,000,000 matches per run.

Run it

  1. Create a free Apify account with $5 in credit.
  2. Open the Football-Data.co.uk Scraper.
  3. Pick your leagues and season range, tick any extra blocks, and click Start.
  4. Export the results as CSV, Excel, JSON, or XML from the Dataset tab.

Run it programmatically through the Apify API or the ApifyClient for JavaScript and Python.

Use with AI agents (MCP)

Give an AI agent live access to the football archive through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:

claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/football-data-couk-scraper"

Then prompt it in plain language:

  • "Pull every Premier League match since 2020 where the away side won at odds above 5.00."
  • "Build me the 2025/26 Serie A table and the head-to-head record for the top two."
  • "Get this weekend's La Liga fixtures with the current Bet365 and Pinnacle prices."

Copy this into ChatGPT, Claude, or Cursor to start:

Use the Apify Actor "parseforge/football-data-couk-scraper" to collect football results and betting odds from Football-Data.co.uk. Input: { "leagues": ["E0"], "extraLeagues": [], "seasonFrom": "2020/21", "seasonTo": "2025/26", "includeOdds1x2": true, "includeBettingAnalytics": true, "maxItems": 500 }. League codes: E0-E3/EC England, SC0-SC3 Scotland, D1/D2 Germany, I1/I2 Italy, SP1/SP2 Spain, F1/F2 France, N1 Netherlands, B1 Belgium, P1 Portugal, T1 Turkey, G1 Greece. Extra league codes: ARG AUT BRA CHN DNK FIN IRL JPN MEX NOR POL ROU RUS SWE SWZ USA. Every extra block is off by default and billed separately. Call it with the ApifyClient and my APIFY_TOKEN.

Troubleshooting

Why are the odds columns empty?

The season predates them. Bet365 prices start in 2002/03, Pinnacle in 2012/13, closing odds and market averages in 2019/20, and the extra leagues carry closing odds only. Check bookmakerCount: zero means the file had no book for that match.

Why are there no shots or cards?

Match statistics start in 2000/01 and the extra leagues never carry them. The block is simply absent on those rows rather than filled with nulls.

Why did my filter return nothing?

Most filters read a column that only exists in some seasons. minAttendance only matches 2000/01 and 2001/02 English, Scottish and German matches; oddsMovement needs closing odds, so 2019/20 onward; minExpectedGoals needs 2026/27.

A league-season came back empty.

Not every division ran in every season. The National League starts in 2005/06, Scottish League One and Two in 1997/98, and Football-Data sometimes publishes a division late, the German Bundesliga file for a new season can lag the others by weeks. The Actor logs the missing file and carries on.

Why is a fixtures run returning old matches?

The main fixtures.csv is refreshed with the week's games. The extra-league fixtures file is updated on Football-Data's own schedule and can sit stale for months; the Actor warns when it does.

Head-to-head or form is slow.

Both blocks index the entire archive of every competition you selected, that is up to 726 downloads before the first row is written. Narrow the leagues if you only need a few.

Team names do not match my other source.

Football-Data uses short forms: Man United, Nott'm Forest, Ath Madrid, Paris SG, Bayern Munich. They are stable across seasons, which makes them good join keys, but they are not the clubs' full names.

FAQ

Question Answer
Do I need an API key or an account? No. Football-Data.co.uk serves these files anonymously.
Do I need a proxy? No. Measured HTTP 200 on every surface without one. A proxy option exists if your own network blocks the site.
How far back does it go? 1993/94 for the biggest divisions, 2012 for the extra leagues.
How many matches are there in total? 304,000+ played matches across 38 competitions.
Which bookmakers are included? Up to 22, depending on the season. Bet365, Pinnacle, William Hill, bwin, Interwetten, BetVictor, VC Bet, Ladbrokes, Betfred, BetMGM, Coral, Paddy Power, Sky Bet, Betfair, Betfair Exchange, 1XBet, Gamebookers, Sportingbet, Stan James, Blue Square, Stanleybet and Sporting Odds.
Does it include expected goals? Yes, where the source has it: Football-Data started publishing xG in 2026/27.
Can I get league tables? Yes, with the League tables checkbox. They are built from every match in the files the run downloaded, so a filtered run still returns a real table.
Is the form block leak-free? Yes. Form and head-to-head are computed only from matches played before that kick-off.
Can I get odds in American or fractional format? Yes, with Odds format. Analytics stay decimal so the maths keeps working.
Why is this not free, when the CSVs are? You are paying for the parsing, the alias resolution, the analytics, and a run you can schedule. If one file is all you need, take the free CSV.
How many matches per run? Free plan: 10. Paid: up to 1,000,000.
Is this an official Football-Data.co.uk product? No. It is unofficial and reads only public files.

Related actors

Browse the full ParseForge collection for more scrapers.

๐Ÿ†˜ Need help? Email parseforge@protonmail.com with your run ID, your input, and what you expected.

โš ๏ธ Disclaimer. This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by Football-Data.co.uk or any bookmaker named in this page. It collects only publicly available files. You are responsible for using the data in compliance with the source's terms and applicable laws. Gambling carries risk: nothing here is betting advice.

Input

FieldTypeWhat it doesDefault
leagues array The 22 divisions Football-Data.co.uk publishes as one file per season, with match statistics and per-bookmaker odds. Coverage starts in 1993/94 for the biggest divisions; the National League starts in 2005/06 and the Scottish lower tiers in 1997/98. ["E0"]
extraLeagues array The 16 non-European-core competitions published as one all-seasons file each, from 2012 onward. These carry closing odds only: no shots, cards, corners or referee. []
countries array Shortcut for picking every division a country has. Adds to whatever you selected above; England alone brings in all five English tiers. []
dataset string (3 options) Played matches from the season archives, the upcoming fixtures file with its opening odds, or both. results
seasonFrom string Oldest season to include. Accepts 2020/21, 2020-21, 2020 or the site's own 2021 code. Leave this empty and it starts at the oldest season the league has; leave both season fields empty and the run returns the two most recent seasons. 2025/26
seasonTo string Newest season to include, same formats as above. Leave it empty to run through to the current season. not set
dateFrom string Drop matches played before this date. Applied on top of the season range. not set
dateTo string Drop matches played after this date. not set
includeMatchStats boolean Referee, shots, shots on target, corners, fouls, free kicks conceded, offsides, woodwork, yellow and red cards, booking points, attendance, expected goals, and the shot-accuracy and conversion rates derived from them. Available from 2000/01 in the main leagues; the extra leagues never carry it. false
includeOdds1x2 boolean Home / draw / away prices from every bookmaker in the file: up to 22 books including Bet365, Pinnacle, William Hill, bwin, Interwetten, BetVictor, Ladbrokes, Betfred, BetMGM, Coral, Paddy Power, Sky Bet, 1XBet and the Betfair Exchange. false
includeClosingOdds boolean The same books priced again just before kick-off. Published from 2019/20 onward. This is the column serious models score themselves against. false
includeOverUnder boolean Over and under 2.5-goal prices, pre-match and closing, per bookmaker plus the market maximum and average. false
includeAsianHandicap boolean The handicap line and its home / away prices, pre-match and closing, per bookmaker plus market maximum and average. false
includeMarketConsensus boolean Best price and mean price across the whole market for 1X2, over/under and Asian handicap, pre-match and closing, plus how many books each average was built from. Includes the retired BetBrain aggregates for older seasons. false
includeBettingAnalytics boolean Implied and margin-free probabilities, bookmaker overround, fair odds, favourite and underdog, best available price, expected-value edge and Kelly fraction, pre-match to closing drift with steamer / drifter flags, closing line value, and the settled profit or loss of a one-unit bet on each outcome. false
includeHeadToHead boolean Every previous meeting between the two sides in that competition before this match: record, average goals, both-teams-scored and over-2.5 rates, the last meeting, and the last five scorelines. Downloads and indexes the division's full archive, so it is the most expensive block here. false
includeTeamForm boolean Rolling record for both sides over their previous matches in that competition: points, points per game, goals for and against, clean sheets, W/D/L form string, current streak and unbeaten run. Also indexes the full archive. false
includeStandings boolean Adds a league-table row per team per competition-season, built from the matches this run collected: position, played, W/D/L, goals, goal difference, points, points per game, split home and away records, clean sheets, both-teams-scored and over-2.5 counts, and recent form. false
formWindow integer How many previous matches the team-form block looks back over. Only used when Team form is on. 6
teams array Keep only matches involving these clubs. Case- and punctuation-insensitive, so "man united" matches "Man United". Football-Data uses short forms: Man United, Tottenham, Ath Madrid, Bayern Munich, Paris SG. []
teamMatchMode string (3 options) Whether the team filter should match the home side, the away side, or either. either
excludeTeams array Drop matches involving any of these clubs. []
referees array Keep only matches with these referees. Football-Data writes them as initial plus surname, e.g. "M Oliver", "A Taylor". []
fullTimeResults array Keep only these full-time outcomes. []
halfTimeResults array Keep only these half-time outcomes. []
minTotalGoals integer Matches with at least this many goals. not set
maxTotalGoals integer Matches with at most this many goals. not set
minHomeGoals integer Home side scored at least this many. not set
maxHomeGoals integer Home side scored at most this many. not set
minAwayGoals integer Away side scored at least this many. not set
maxAwayGoals integer Away side scored at most this many. not set
minGoalDifference integer Keep only matches won by at least this many goals. not set
bothTeamsScored string (3 options) Filter on whether both sides got on the scoresheet. any
comebacksOnly boolean Keep only matches where the side trailing at half time did not lose. false
daysOfWeek array Keep only matches played on these days. []
kickoffFrom string Earliest kick-off time to keep, as HH:MM in the time the site publishes. Kick-off times exist from 2019/20 onward. not set
kickoffTo string Latest kick-off time to keep, as HH:MM. not set
minShots integer Combined shots by both sides. Needs a season that carries match statistics. not set
minShotsOnTarget integer Combined shots on target by both sides. not set
minCorners integer Combined corners by both sides. not set
minFouls integer Combined fouls by both sides. not set
minYellowCards integer Combined yellow cards. not set
minRedCards integer Combined red cards. Set to 1 for matches with a sending off. not set
minAttendance integer Crowd size. Only the 2000/01 and 2001/02 English, Scottish and German files carry attendance. not set
minExpectedGoals number Combined expected goals. Football-Data started publishing xG in 2026/27. Decimal, e.g. 2.5. not set
minHomeOdds number Reference home price, read from the market average and falling back to Pinnacle, then Bet365, then whatever book the file carries. Decimal, e.g. 1.50. not set
maxHomeOdds number Upper bound on the reference home price. Decimal, e.g. 3.00. not set
minDrawOdds number Lower bound on the reference draw price. Decimal, e.g. 3.00. not set
maxDrawOdds number Upper bound on the reference draw price. Decimal, e.g. 5.00. not set
minAwayOdds number Lower bound on the reference away price. Decimal, e.g. 2.00. not set
maxAwayOdds number Upper bound on the reference away price. Decimal, e.g. 10.00. not set
minOverround number Lower bound on the overround of the reference 1X2 prices, as a fraction: 0.05 means a 5% margin. Decimal, e.g. 0.05. not set
maxOverround number Upper bound on the overround. Use it to keep only the sharpest-priced matches. Decimal, e.g. 0.03. not set
minBookmakerCount integer Keep only matches priced by at least this many bookmakers in the 1X2 market, counting whichever of the pre-match or closing lines the file carries. Useful for dropping thinly-quoted fixtures from a model. not set
favourite string (4 options) Keep only matches where the shortest price belonged to this side. any
upsetsOnly boolean Keep only matches the longest-priced outcome won. false
upsetMinOdds number With Upsets only on, also require the winning price to be at least this long. Decimal, e.g. 4.00. not set
oddsMovement string (3 options) Keep only matches whose price shortened (steamer) or lengthened (drifter) between the pre-match and closing lines. Needs a season with closing odds: 2019/20 onward. any
minOddsMovementPct number How far the price must have moved, in percent, for the movement filter to keep the match. not set
maxItems integer Total rows to write in this run. Free Apify plans return a 10-row preview. 100
matchesPerLeague integer Cap the matches taken from each competition so one league cannot use up the whole run. Leave empty to let Maximum rows decide. not set
sortBy string (7 options) Leave on "Source order" to stream results as they download, newest season first. Any other choice buffers the whole selection in memory before writing. none
oddsFormat string (3 options) How odds are printed in the odds blocks. Analytics always stay decimal so the maths keeps working. decimal
proxyConfiguration object Not needed: Football-Data.co.uk serves these files anonymously with no rate limit measured. Turn it on only if your own network blocks the site. {"useApifyProxy":false}

Pricing

from $2.67 per 1,000 results

Charged forWhat it isPrice each
Actor Start Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). $0.04801 to $0.054
Season file Charged once for each Football-Data.co.uk CSV downloaded for your selection. This is the fixed cost of a league-season, shared by every match it yields. $0.01778 to $0.02
Match Charged once per match row written, after every filter has run. Filtered-out matches are free. $0.00267 to $0.003
Match statistics Charged only when Match statistics is on and the source file carried shots, cards, corners, referee, attendance or expected goals for that match. $0.00089 to $0.001
Pre-match 1X2 odds Charged only when Pre-match 1X2 odds is on and at least one bookmaker priced that match. $0.00133 to $0.0015
Closing 1X2 odds Charged only when Closing 1X2 odds is on and at least one bookmaker's closing price is in the file. $0.00133 to $0.0015
Over / under odds Charged only when Over / under 2.5 goals is on and the match carries those prices. $0.00089 to $0.001
Asian handicap odds Charged only when Asian handicap odds is on and the match carries a handicap line. $0.00089 to $0.001
Market maximum and average Charged only when Market maximum and average is on and the file carries market-wide best and mean prices. $0.00089 to $0.001
Betting analytics Charged only when Betting analytics is on: implied and fair probabilities, overround, value edge, Kelly, odds drift, closing line value and settled P/L. $0.00178 to $0.002
Head-to-head history Charged only when Head-to-head history is on. Building it downloads and indexes the full archive of every competition selected. $0.00267 to $0.003
Team form Charged only when Team form is on: both sides' rolling record going into the match, computed from the indexed archive. $0.00178 to $0.002
League table row Charged per league-table row written, only when League tables is on. $0.00889 to $0.01

Tiered: the lower figure is the price on a higher Apify plan. Billing and the free credit live on Apify.

API

One POST returns the dataset directly. Same shape for every scraper in the library, so swapping the slug is the only change.

POST ยท run and get results
curl -X POST "https://api.apify.com/v2/acts/parseforge~football-data-couk-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "helloWorld": 123
  }'

Examples

Input that runs as-is.

input.json
{
  "helloWorld": 123
}

Reviews

No reviews yet. Be the first.

Issues

We build and maintain this scraper, so a problem with it comes to us. Report it on the Apify listing and the thread stays attached to the scraper where the next person can find it: open an issue.

Broken and urgent, or you would rather not post in public? Write to parseforge@protonmail.com and it reaches the people who wrote it.

Related scrapers

Run Football-Data.co.uk Scraper - Results, Stats & Odds on Apify All scrapers