---
name: footballsoccerapi
description: Football (soccer) data from footballsoccerapi.com, back to 2012 in over 150 countries. Use when an agent needs fixtures, results, live scores, lineups, match statistics, standings, team form, head to head or exchange prices at kickoff and half-time.
---

# footballsoccerapi.com

A REST API and MCP server over an archive of football matches since 2012: fixtures, results, live scores, lineups, match statistics, grounds, officials, standings and exchange prices at kickoff and half-time. Operated by DeveloperData.net.

## When to use it

- Use it for match facts: who played, the score, when, where, the lineups, the statistics, the table, a club's form, prices at kickoff.
- Use it to count things across many matches (home advantage, scorelines, how favourites fare) instead of guessing.
- Do not use it for news, transfers, injuries, betting tips or predictions. It holds facts, not opinions.

## Access

1. Get a free key at https://footballsoccerapi.com/free-key (sign in with a Google account; no card, nothing charged).
2. Send it on every call in the `X-API-Key` header. Never put a real key in code you share.
3. Base URL: `https://api.footballsoccerapi.com/v1`. Every response is JSON with `data` and `meta`.

Ids are opaque strings (`lg_24T9Z0G` for a competition, `tm_1E5HXK9` for a club, `mt_1JK5QJ9` for a match). Find them with the search calls; never build one. Times are UTC, ISO 8601.

## Calls that answer the common questions

Find a competition, then its matches:

```
curl "https://api.footballsoccerapi.com/v1/leagues?country=England" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/matches?league_id=lg_24T9Z0G&season=2024&status=finished&limit=50" -H "X-API-Key: $FSAPI_KEY"
```

```json
{"data":[{"match_id":"mt_1JK5QJ9","league_name":"Premier League","kickoff_utc":"2025-05-25T15:00:00Z",
  "home_team_name":"...","away_team_name":"...","home_goals":2,"away_goals":1,"full_time_result":"home"}],
 "meta":{"request_id":"...","total":380,"next_cursor":"MTcy..."}}
```

Find a club, then its form or a head to head:

```
curl "https://api.footballsoccerapi.com/v1/teams?q=Arsenal" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/teams/tm_1E5HXK9/form" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/teams/tm_1E5HXK9/head-to-head/tm_0B7QW2D" -H "X-API-Key: $FSAPI_KEY"
```

One match in full, then its lineups and statistics:

```
curl "https://api.footballsoccerapi.com/v1/matches/mt_1JK5QJ9" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/matches/mt_1JK5QJ9/lineups" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/matches/mt_1JK5QJ9/statistics" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/matches/mt_1JK5QJ9/players" -H "X-API-Key: $FSAPI_KEY"
```

Player figures carry a `player_id` (`pl_...`) that stays the same across matches.

Today and what is next:

```
curl "https://api.footballsoccerapi.com/v1/results/today?country=Spain" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/fixtures/upcoming?league_id=lg_24T9Z0G" -H "X-API-Key: $FSAPI_KEY"
curl "https://api.footballsoccerapi.com/v1/live" -H "X-API-Key: $FSAPI_KEY"
```

A league table:

```
curl "https://api.footballsoccerapi.com/v1/standings/lg_24T9Z0G/2024" -H "X-API-Key: $FSAPI_KEY"
```

A whole season as one file (Archive plan and above, one call per hundred matches):

```
curl -o premier-league-2024.csv "https://api.footballsoccerapi.com/v1/export/lg_24T9Z0G/2024?format=csv" -H "X-API-Key: $FSAPI_KEY"
```

Every endpoint, parameter and sample response: https://footballsoccerapi.com/documentation/manual.md (one markdown file) and https://api.footballsoccerapi.com/v1/openapi.json.

## MCP server

- URL: `https://footballsoccerapi.com/mcp` (streamable HTTP). Authenticate with the API key as a bearer token: `Authorization: Bearer <key>`.
- Claude Code: `claude mcp add --transport http football https://footballsoccerapi.com/mcp --header "Authorization: Bearer $FSAPI_KEY"`
- Tools: `search_matches`, `get_match`, `get_match_odds`, `get_match_lineups`, `get_match_statistics`, `get_match_players`, `get_match_events`, `list_countries`, `list_competitions`, `find_club`, `get_standings`, `get_team_form`, `get_head_to_head`, `get_fixture_preview`, `get_fixtures_today`, `get_league_stats`, `get_home_advantage`, `get_price_calibration`, `run_backtest`.

## Limits

| Plan | Per minute | Allowance | Reaches |
|---|---|---|---|
| Free key | 60 | 50 calls a day, reset 00:00 UTC | Yesterday, today and the fixtures ahead; no statistics, lineups, player figures or prices |
| Archive | 120 | 250,000 calls a month | Everything back to 2012 |
| Live | 180 | 600,000 calls a month | Archive plus in-play, live prices, previews and webhooks |

- Headers on every reply: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`; `Retry-After` on a 429.
- Lists take `limit` (1 to 1000, default 100) and page with `page` or `cursor` (pass `meta.next_cursor` back unchanged).
- `/v1/matches?ids=` takes up to 50 match ids separated by a dash.
- `GET /v1/usage` shows what is left today. `GET /v1/status` and https://footballsoccerapi.com/status show how current the data is.
- Lineups and statistics exist only where the match had them; an empty list is an answer, not an error.

## Errors

Every error has the same shape:

```json
{"error":{"code":"plan_required","message":"Archive is needed for this endpoint.","your_plan":"free","needs_plan":"archive","upgrade_url":"/pricing"},
 "meta":{"request_id":"01J9QW3C7M4KX2VB"}}
```

| Status | Codes | What to do |
|---|---|---|
| 400 | `invalid_parameter`, `invalid_id`, `invalid_ids`, `too_many_ids` | Fix the request; the message names the field. |
| 401 | `missing_key`, `unknown_key`, `revoked_key` | Send a valid key in `X-API-Key`. |
| 403 | `plan_required`, `outside_plan_window` | The key's plan does not reach this; say so, do not retry. |
| 404 | `not_found` | The id does not exist; search again. |
| 429 | `rate_limited`, `quota_exhausted` | Wait `Retry-After` seconds, or until 00:00 UTC for the daily allowance. |
| 503 | `archive_unavailable` | Try again shortly. |

## Typical workflow

1. Resolve names to ids: `/v1/leagues` or `/v1/teams?q=`, or `find_club` and `list_competitions` over MCP.
2. Ask the narrowest call that answers the question (`/v1/matches` with filters, `/form`, `/head-to-head`, `/standings`).
3. Page with `meta.next_cursor` only while the answer needs more rows.
4. For one match, fetch `/v1/matches/{id}`, then `/lineups` or `/statistics` if the question needs them.
5. Quote figures as the API returned them, with the match date in UTC, and say when a field was empty.
6. On 403 or 429, tell the user what the plan reaches or when the allowance resets; do not loop.
