The free key reads yesterday again: our one-month trial of today on the free key has finished. Read the changelog
1,689,164 matches · updating now

The football API
that returns the whole match,
not just the score.

Fourteen seasons of fixtures, results, lineups, match statistics, grounds, referees and exchange prices at kickoff — one REST call, one JSON object, every field documented and counted from the archive rather than estimated.

50 calls a day free No card OpenAPI, Postman, MCP
bash 200 OK
— response · 64 endpoints · back to 2012
1,689,164Matches, every field the same
1,137Competitions in 171 countries
28,325Clubs with full history
2012Earliest season held
01 · The archive

Ten seasons deep,
1,380 competitions wide.

1,689,164 matches, every one with its own fixture id, the same field names and the same club ids — from the Premier League down to the Namibian top flight.

Browse the coverage →
1,689,164
Matches
Ten seasons, 2017 to 2026, growing every night.
1,380
Competitions
1,137 leagues across 171 countries, 10,688 league-seasons in all.
28,325
Clubs
One id per club, stable across every season it appears in.
BHA NEW LIV WOL CEL + 5,937 more
171Countries
1,137Leagues
10,688League-seasons
1,380Divisions
Where the depth actually is
Counted from the archive, not estimated
1994
5,903
1995
6,356
1996
7,365
1997
8,102
1998
9,529
1999
9,922
2000
7,905
2001
7,897
2002
7,664
2003
8,047
2004
8,169
2005
8,801
2006
8,852
2007
9,005
2008
9,134
2009
8,791
2010
10,105
2011
10,439
2012
32,640
2013
37,664
2014
37,744
2015
40,665
2016
61,493
2017
63,832
2018
73,968
2019
115,503
2020
130,718
2021
150,780
2022
157,599
2023
166,512
2024
173,285
2025
164,490
2026 in progress
104,860
Every season carries the same fields — nothing thins out as you go back. 2026 fills nightly through to December
England 46 leagues
155,287
World 313 leagues
131,793
Spain 38 leagues
88,442
Germany 34 leagues
73,865
Italy 31 leagues
64,630
France 24 leagues
60,263
Brazil 109 leagues
55,073
Belgium 28 leagues
44,228
Turkey 11 leagues
38,769
Argentina 14 leagues
36,509
And 85 more countries — Kenya 5,303, Iceland 4,095, Mongolia 756, Namibia 150. No coverage tiers, no per-league add-ons
02 · Anatomy of a row

Every match carries the context
most feeds drop.

Anyone can give you a scoreline. These are the fields that let you ask why — and they sit on the same row, in the same response, with no second call.

Read the field reference →
Where they stood at kickoff
Both sides' league position on the day, computed from the same rows — not the table as it looks today.
5Newcastleaway
11Brightonhome
home_league_positionaway_league_position
How far the away side came
Great-circle distance between the two clubs' grounds, on every match in the archive.
462 km
NewcastleBrighton
away_travel_km
Where it was played
Stadium, city and coordinates for both clubs, so you can group by geography or weather.
Amex Stadium 50.8616, −0.0837
venue_namecity_namelatitudelongitude
Who refereed
The named official on the match, and the fill rate printed beside it rather than assumed.
Thomas BramallReferee
34.5%of matches carry one
referee_name
The clock, properly
Both halves timestamped, added time recorded, and a flag when the kickoff itself was moved.
First half started 19:00:42
Second half started 19:47:15
Added time +7 min
Kickoff moved false
half_start_firsthalf_start_secondstoppage_minutesis_kickoff_rescheduled
What happened, minute by minute
Goals and cards as a timeline on the match, so half-time prices have something to explain them.
23 HT 58 74
0'45'90'+7
match_eventshalf_time_result
The whole row, grouped
Whole-word names, the unit in the name, no legacy abbreviations
Full field reference →
Identity7 fields
match_idcountry_nameleague_idleague_namedivision_codehome_team_idaway_team_id
Timing6 fields
kickoff_utckickoff_dateseason_start_yearmatch_statushalf_start_firsthalf_start_second
Result8 fields
home_goalsaway_goalsfull_time_resulthalf_time_home_goalshalf_time_away_goalshalf_time_resultstoppage_minutesresult_status
Context9 fields
home_league_positionaway_league_positionaway_travel_kmvenue_namecity_namelatitudelongitudereferee_namematch_events
Marketsee section 03
home_kickoff_pricehome_half_time_pricematched_kickoff_volumeoverroundmatched_prematch_volumebetfair.market_id
Freshness4 fields
created_utcupdated_utcdata_as_ofrequest_id
Referee, match events and half-time prices exist wherever the record carries them — every league page prints the fill rate, and no field is ever claimed as universal. One call, one row, no joins
03 · The market, twice

Anyone can sell you a scoreline.
We sell you what the money thought.

Exchange prices, not a bookmaker's book — so there's no margin baked into the number. Captured at kickoff, captured again at half-time, with the matched volume behind each one.

See the odds endpoints →
One market, two snapshots
Three-way match odds, same market, 47 minutes apart
Brighton 2–1 Newcastle · HT 1–0
OutcomeKickoff, then half-timeDrift
Brightonhome
KO2.1446.7%
HT1.6261.7%
▲ 15.0
Draw
KO3.6527.4%
HT3.9025.6%
▼ 1.8
Newcastleaway
KO3.5528.2%
HT7.4013.5%
▼ 14.7
No margin in the pricelower is fairer
Exchange, kickoff 102.3%
Exchange, half-time 100.8%
Typical bookmaker 105–108%

A three-way book at 106% has the margin built in before you start. At 102.3% the price is close enough to the crowd's real probability to model against — which is the only kind worth storing ten seasons of.

The money behind the price
Matched volume before the match and again at kickoff — a thin market and a deep one are not the same number.
Pre-match
£412,880
At kickoff
£1,284,930
matched_prematch_volumematched_kickoff_volume
How much of the archive is priced
We print the real number rather than implying every match has a market on it.
761,582matches priced at kickoff
45.1% of the archiveof 1,689,164
has_pricesodds/kickoff
Joins to your own market data
Market, event and selection ids travel on the row, so our archive stitches straight onto your own logs.
market_id1.248871903
event_id34118226
selection_ids3 runners
betfair.market_idbetfair.event_idbetfair.selection_ids
Every price on this page is Archive

Ten seasons settled to yesterday, both snapshots on every priced match, matched volume, overround and the market ids — plus backtesting and CSV export over the lot.

/v1/odds/kickoff /v1/odds/half-time /v1/odds/overround /v1/odds/volume /v1/odds/bands POST /v1/backtest
$49
per month · cancel any time
Start with Archive
04 · Coverage

171 countries.
No coverage tiers, no add-ons.

Every country below is in the archive on the same schema, and the free key reaches all of them for yesterday, as one whole day. What separates the plans is how far back you can read and whether the prices come with it, never which league it came from.

Browse every league →
Every country in the archive
Counted at build time, sorted by depth
171 of 171
England 46 leagues 155,287
World 313 leagues 131,793
Spain 38 leagues 88,442
Germany 34 leagues 73,865
Italy 31 leagues 64,630
France 24 leagues 60,263
Brazil 109 leagues 55,073
Belgium 28 leagues 44,228
Turkey 11 leagues 38,769
Argentina 14 leagues 36,509
Austria 20 leagues 34,293
Scotland 12 leagues 30,024
USA 16 leagues 29,673
Portugal 19 leagues 25,849
Sweden 16 leagues 25,607
Netherlands 14 leagues 25,526
Czech Republic 17 leagues 23,314
Greece 17 leagues 23,033
Australia 25 leagues 21,276
Japan 9 leagues 20,861
Denmark 14 leagues 19,086
Poland 11 leagues 18,474
Norway 17 leagues 18,047
Switzerland 16 leagues 18,003
Russia 16 leagues 17,975
Mexico 12 leagues 17,793
Hungary 8 leagues 17,186
Romania 16 leagues 16,142
Bulgaria 9 leagues 15,123
Finland 12 leagues 13,735
Serbia 8 leagues 13,595
Croatia 10 leagues 13,322
Belarus 6 leagues 12,835
Ukraine 8 leagues 12,273
Israel 6 leagues 11,967
Slovakia 9 leagues 10,694
Algeria 6 leagues 10,496
Albania 7 leagues 9,902
Thailand 5 leagues 9,691
Colombia 5 leagues 9,197
Venezuela 4 leagues 8,909
Guatemala 2 leagues 8,818
South Korea 6 leagues 7,888
Wales 4 leagues 7,840
Saudi Arabia 7 leagues 7,811
Egypt 8 leagues 7,261
South Africa 8 leagues 7,102
China 5 leagues 7,051
Bosnia 5 leagues 7,003
Uruguay 6 leagues 6,872
Georgia 5 leagues 6,829
Peru 7 leagues 6,793
Kenya 4 leagues 6,697
Estonia 4 leagues 6,556
Iceland 9 leagues 6,412
Chile 6 leagues 6,327
Northern Ireland 7 leagues 6,232
Ecuador 4 leagues 6,224
Cyprus 5 leagues 6,060
United Arab Emirates 6 leagues 6,041
Kazakhstan 4 leagues 5,870
Paraguay 5 leagues 5,846
Iran 4 leagues 5,825
Lithuania 4 leagues 5,696
Costa Rica 5 leagues 5,326
Latvia 4 leagues 5,251
Tunisia 4 leagues 5,202
Slovenia 5 leagues 5,181
Azerbaijan 3 leagues 4,993
Indonesia 4 leagues 4,993
Ghana 4 leagues 4,806
Morocco 3 leagues 4,677
Armenia 4 leagues 4,632
Macedonia 3 leagues 4,491
Malta 5 leagues 4,236
Nigeria 2 leagues 4,104
Faroe Islands 4 leagues 4,052
Zambia 1 league 4,041
Benin 1 league 3,989
Qatar 6 leagues 3,919
Cameroon 3 leagues 3,901
El Salvador 2 leagues 3,874
India 7 leagues 3,796
Uzbekistan 4 leagues 3,711
Hong Kong 8 leagues 3,696
Luxembourg 2 leagues 3,605
Bolivia 4 leagues 3,582
Angola 2 leagues 3,529
Uganda 1 league 3,479
Vietnam 4 leagues 3,437
Montenegro 3 leagues 3,177
Nicaragua 3 leagues 3,161
Andorra 4 leagues 2,955
Ireland 6 leagues 2,921
Honduras 1 league 2,908
Jamaica 1 league 2,864
Ethiopia 2 leagues 2,829
Malaysia 5 leagues 2,828
Tanzania 1 league 2,757
Moldova 3 leagues 2,701
Mali 1 league 2,694
Zimbabwe 1 league 2,685
Oman 4 leagues 2,683
Kuwait 5 leagues 2,547
Iraq 1 league 2,505
Canada 6 leagues 2,501
Guadeloupe 1 league 2,491
Haiti 1 league 2,403
Sudan 1 league 2,361
Congo DR 1 league 2,236
San Marino 3 leagues 2,227
Botswana 1 league 2,207
New Zealand 7 leagues 2,188
Jordan 4 leagues 2,100
Rwanda 1 league 2,096
Guinea 1 league 1,997
Kosovo 4 leagues 1,962
Ivory Coast 1 league 1,953
Libya 1 league 1,889
Senegal 1 league 1,880
Panama 1 league 1,852
Lebanon 3 leagues 1,831
Burundi 1 league 1,799
Burkina Faso 1 league 1,795
Suriname 1 league 1,676
Myanmar 1 league 1,651
Syria 1 league 1,564
Bahrain 4 leagues 1,557
Tajikistan 1 league 1,553
Cambodia 2 leagues 1,502
Palestine 1 league 1,476
Malawi 1 league 1,453
Bangladesh 2 leagues 1,450
Gambia 1 league 1,384
Trinidad And Tobago 1 league 1,321
Kyrgyzstan 1 league 1,316
Eswatini 1 league 1,312
Singapore 3 leagues 1,278
Aruba 1 league 1,210
Mauritania 1 league 1,161
Liberia 1 league 1,050
Lesotho 1 league 1,018
Congo 1 league 957
Gibraltar 3 leagues 866
Bermuda 1 league 850
Mongolia 2 leagues 837
Chinese Taipei 1 league 802
Turkmenistan 2 leagues 770
Dominican Republic 2 leagues 747
Belize 1 league 646
Barbados 1 league 617
Philippines 2 leagues 567
Fiji 1 league 552
Bhutan 2 leagues 533
Somalia 1 league 473
Gabon 1 league 470
Curacao 1 league 426
Antigua And Barbuda 1 league 425
Togo 1 league 422
Laos 1 league 404
Cuba 1 league 382
Nepal 1 league 364
Mauritius 1 league 360
Macao 1 league 332
Grenada 1 league 280
Maldives 1 league 197
Crimea 1 league 187
Namibia 1 league 150
Pakistan 1 league 132
Liechtenstein 1 league 106
Yemen 1 league 78
Nothing matches that. We cover 171 countries — try a shorter search.
The tail is real and we print it: Namibia 150, Pakistan 132, Liechtenstein 106, Yemen 78. 1,689,164 matches · 1,137 leagues · 1,380 competitions
The free key reaches every league

Not a sample, not three showcase leagues. Every country on this list, on a real key, for yesterday, as one whole day.

Get a free key →
One schema, top to bottom

Namibia’s top flight returns the same field names as the Premier League. Write the parser once and point it anywhere.

Field reference →
Ids that don’t move

28,325 club ids stable across every season a club appears in, and one match id per fixture — so what you store today still joins next year.

How ids work →
05 · What you can build

Four things people build with it,
and the call that starts each one.

No SDK to install, no schema to learn twice. Every one of these is a copy-paste snippet on the documentation page it belongs to.

Open the quickstart →
Train a model on settled prices

Ten seasons of results with the price they went off at, plus positions and travel — cursor-paged, a thousand rows a call.

Archive
cURL
curl "…/v1/matches?season=2017-2025&has_prices=true
     &include=odds,context&limit=1000&cursor=$c" \
  -H "X-API-Key: $FSAPI_KEY"
/v1/matches/v1/odds/kickoff Guide →
Run a live fixtures board

Today's card, in-play scores and current prices, asked once a minute; nothing comes back until something has changed.

Live
JavaScript
let since = "";
setInterval(async () => {
  const r = await fetch("https://api.…/v1/live",
    { headers: { "X-API-Key": key, "If-Modified-Since": since } });
  if (r.status === 304) return;   // nothing changed
  since = r.headers.get("Last-Modified");
  (await r.json()).data.forEach(board.update);
}, 60000);
/v1/fixtures/today/v1/livewebhooks Guide →
Drive a results and stats site

A page per club and per league — form, standings, head-to-head — off one archive with stable ids.

Free key
PHP
$form = fsapi("/v1/teams/{$id}/form?last=10");
$table = fsapi("/v1/standings/{$league}/2026");

// 28,325 clubs, one id each, stable across seasons
/v1/teams/{id}/form/v1/standings Guide →
Hand it to an assistant

Point an agent at the MCP endpoint and it queries the archive itself — no glue code to write.

Archive
Agent prompt
// tools: fsapi.matches, fsapi.team_stats, fsapi.odds

"How does Brighton do at home when they
 lead at half-time, and what did the market
 pay at kickoff in those games?"
POST /mcp/v1/teams/{id}/stats Guide →
Whatever you're writing it in, there's a snippet

Every endpoint page carries the same call in four languages and a Run it live box that fires against your own key — so you can check the shape of the response before you write a line.

cURLJavaScriptPythonPHP
06 · The full API

70 endpoints,
all of them documented.

Generated from the same registry that drives the router, the OpenAPI export, the Postman collection and the assistant tools — so this list can't drift from what the API actually serves.

Read the documentation →
Endpoint explorer
9 sections, plus the push and assistant channel
70 endpoints
Nothing matches that.
F Free key A Archive L Live Every refusal names the plan it needs and links to pricing — never a bare 403.
OpenAPI 3.1

The whole surface as a spec you can generate a client from, regenerated on every release.

Download the spec →
Postman collection

Every endpoint with example parameters, ready to fire once you paste your key into the environment.

Import the collection →
MCP tools

The same registry exposed as assistant tools, so an agent can query the archive without glue code.

Connect an assistant →
07 · The Lab

A free lab that tests the systems
other people sell you.

Every popular football system run against the whole archive at kickoff prices, net of commission, with the losing ones shown losing. Rebuilt nightly. No sign-in to read any of it.

Open the Lab →
Systems, tested honestly
Level stakes at kickoff price · 2% commission on winnings
Sample
Back the home favourite under 1.80
Top five European leagues · 2017–2026 · 12,486 qualifying matches
12,486
Bets
54.8%
Strike rate
−3.1%
ROI, net
−18.4%
Max drawdown
Also on the board
Lay the draw, top five leagues41,208 bets−2.4%
Back the side leading at half-time26,741 bets−2.9%
Back away sides travelling under 100 km8,930 bets−1.8%
Top-four at home against the bottom six5,612 bets+0.4%
A 54.8% strike rate that still loses money is the whole point — the commission and the margin eat it. We publish the ones that fail as prominently as the ones that don't.
Is the market actually right?
Implied probability against what happened
Sample
Implied by price Actually won
1.01 – 1.50+0.5
Implied76.9%
Actual77.4%
1.50 – 2.00+0.5
Implied57.1%
Actual57.6%
2.00 – 3.00+0.2
Implied40.0%
Actual40.2%
3.00 – 5.00−0.6
Implied25.0%
Actual24.4%
5.00 and out−0.9
Implied12.5%
Actual11.6%
Across 761,582 priced matches the market is close to right — favourites edge ahead, long shots fall short. Small, consistent, and only visible with ten seasons of settled prices.
Read it free. Run your own when you're ready.

The whole Lab is open — no account, no email wall. When you want to test your rule rather than ours, the same engine is one endpoint away on Archive.

POST /v1/backtest /v1/odds/bands /v1/odds/kickoff /v1/stats/half-time
08 · Built to be relied on

Boring where it counts.
v1 only ever gains fields.

You can see the uptime, you can see how old the answer is, and you can see what changed and when. Nothing about this API should ever be a surprise on a Monday morning.

Open the status page →
All systems operational. Checked every few minutes; the same checks as the status page data_as_of 2026-10-22T07:05:23Z
REST API70 endpoints99.39%
90 days agotoday
Results and fixturesfinished matches and the cards ahead100%
90 days agotoday
Live scoresin-play scores and events98.96%
90 days agotoday
Nightly rebuild03:45 UTC, every night100%
90 days agotoday
One rebuild a night, one data_as_of, so every response tells you exactly how old it is. Open the status page
Every response tells you where you stand
Headers on success, and a refusal that names the way forward
Response headers 200 OK
data-as-of: 2026-09-04T02:10:00Z
x-request-id: 01J9QW3C7M4KX2VB
x-ratelimit-limit: 120
x-ratelimit-remaining: 118
x-ratelimit-reset: 41
Asking for something above your plan 403
{
  "error": {
    "code": "plan_required",
    "message": "Half-time prices need the Archive plan.",
    "your_plan": "free",
    "needs_plan": "archive",
    "upgrade_url": "/pricing?from=odds"
  },
  "meta": { "request_id": "01J9QW3C7M4KX2VB" }
}
v1 only ever gains fields

Adding a field is routine and needs nothing from you. Removing one is a changelog event with a deprecation window, announced before it happens — never on the day.

A changelog you can follow

Every release dated, with what changed and what it affects. Subscribe by email or RSS and you'll know before your code does.

Read the changelog →
Support is a thread, not an inbox

Tickets carry a reference and stay readable from your account. Quote a request_id and we can see the exact call you made.

Open a ticket →
09 · Pricing

Two paid plans.
Honest limits printed on both.

No seat pricing, no per-call surcharges, no coverage upsell. Cancel from your account and keep access to the end of the period you paid for.

Free key
Real data on a real key: yesterday, as one whole day.
$0forever
No card, no trial clock
16endpoints
of 70
  • Every league, for yesterday, as one whole day
  • Yesterday's results, settled and final, from every competition
  • Full read of the Lab, no account needed
  • No today, fixtures ahead, in-play feed, prices, statistics or older seasons
60 / min50 / day
Sign in with Google
Most popular
Archive
Ten seasons settled to yesterday, with every price we hold.
$49per month
Billed monthly · cancel any time
62endpoints
of 70
  • Everything settled up to yesterday 23:59 UTC
  • Kickoff and half-time prices, matched volume, overround, market ids
  • Every stats, standings, form and head-to-head endpoint
  • Backtesting on your own rules, and MCP tools for assistants
120 / min250,000 / month
Start with Archive
Live
Everything in Archive, with today and tomorrow as well.
$149per month
Billed monthly · cancel any time
70endpoints
all of them
  • Everything in Archive, with no date guard at all
  • Today's card, fixtures ahead, in-play scores and events, current prices
  • Webhooks on kickoff, goals, red cards, lineups and results
  • Fixture previews with form and market before kickoff
180 / min600,000 / month
Start with Live
Limits are printed, not hidden
Per-minute and per-month, on the page and in your headers.
Cancel from your account
One click, no email, access runs to the end of the period.
Move up or down any time
Change plan and the difference is prorated automatically.
Over the limit isn't a bill
You get a 429 with a reset time, never a surprise invoice.
1,689,164 matches waiting

Take the free key.
It's real data.

Every league and every country, for yesterday, as one whole day, 50 calls a day. No card, no trial clock, and no sandbox rows for matches that were never played.

$ curl "https://api.footballsoccerapi.com/v1/countries" -H "X-API-Key: $FSAPI_KEY"
Nothing to install Upgrade only when it fits Cancel any time

16 endpoints · 60 calls a minute · 500 a day · every league in the archive