> ## Documentation Index
> Fetch the complete documentation index at: https://www.thestatsapi.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For the complete API reference (every endpoint, query parameter and response field), fetch https://api.thestatsapi.com/llms.txt. Only use endpoints, parameters and fields listed there.
> Base URL: https://api.thestatsapi.com/api. Auth header: Authorization: Bearer YOUR_API_KEY. Keep the key in server-side code only.

# Get fixtures and results

> Get a team's next fixture, latest results, one day's matches, a matchday or a tournament group from /football/matches, with date ranges, time zones and sort order.

Use `/football/matches` to get upcoming fixtures and finished results for a team, competition, date range or matchday.

<Tip>
  **Fastest way: ask your AI.** Set up your coding tool once with [Build with AI](/docs/build-with-ai), then paste:

  ```text Prompt wrap theme={null}
  Using TheStatsAPI (reference: https://api.thestatsapi.com/llms.txt), build a server route that returns Arsenal's next 5 fixtures and last 5 results with scores. Keep the API key server-side.
  ```
</Tip>

## The filters you'll use most

| Parameter | What it does |
| - | - |
| `team_id` | Matches this team plays, home or away. |
| `competition_id`, `season_id` | Matches in a competition or season. The season must belong to the competition. |
| `status` | `scheduled`, `live`, `finished`, `postponed` or `cancelled`. |
| `date_from`, `date_to` | Kickoff date range, `YYYY-MM-DD`. There is no `date` parameter. |
| `utc_offset` | Time zone for reading the dates, e.g. `-05:00`. Defaults to UTC. |
| `sort` | `-utc_date` (default) is newest first. `utc_date` is soonest first. |
| `matchday`, `stage`, `group` | A league round, regular season vs play-offs, or a tournament group. |
| `page`, `per_page` | 20 per page by default, 100 at most. |

The JavaScript examples run on your server and read your key from the `THESTATSAPI_API_KEY` environment variable.

## Next fixture for a team

Ask for scheduled matches, soonest first, and take the first one.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.thestatsapi.com/api/football/matches?team_id=tm_9145&status=scheduled&sort=utc_date&per_page=1" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    team_id: "tm_9145",
    status: "scheduled",
    sort: "utc_date",
    per_page: "1",
  });
  const res = await fetch(`https://api.thestatsapi.com/api/football/matches?${params}`, {
    headers: { Authorization: `Bearer ${process.env.THESTATSAPI_API_KEY}` },
  });
  const { data } = await res.json();
  const next = data[0];
  console.log(`${next.home_team.name} v ${next.away_team.name}, ${next.utc_date}`);
  ```
</CodeGroup>

Response (trimmed):

```json Response theme={null}
{
  "data": [
    {
      "id": "mt_200199332",
      "competition_id": "comp_3039",
      "season_id": "sn_8406098",
      "matchday": 6,
      "status": "scheduled",
      "utc_date": "2026-10-10T11:30:00.000Z",
      "home_team": { "id": "tm_9145", "name": "Arsenal" },
      "away_team": { "id": "tm_0256", "name": "Leeds United" },
      "score": { "home": null, "away": null, "winner": null },
      "odds_available": true,
      "live_odds_available": false
    }
  ],
  "meta": { "page": 1, "per_page": 1, "total": 9, "total_pages": 9 }
}
```

Use `per_page=5` for the next five. Kickoff times (`utc_date`) are always UTC.

<Warning>
  Without `sort=utc_date` you get the newest kickoff first, which for scheduled matches is the one furthest in the future.
</Warning>

## Latest results

Results come newest first by default, so you don't need `sort`.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.thestatsapi.com/api/football/matches?team_id=tm_9145&status=finished&per_page=1" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(
    "https://api.thestatsapi.com/api/football/matches?team_id=tm_9145&status=finished&per_page=1",
    { headers: { Authorization: `Bearer ${process.env.THESTATSAPI_API_KEY}` } }
  );
  const { data } = await res.json();
  const last = data[0];
  console.log(`${last.home_team.name} ${last.score.home}-${last.score.away} ${last.away_team.name}`);
  ```
</CodeGroup>

Response (trimmed):

```json Response theme={null}
{
  "data": [
    {
      "id": "mt_155834755",
      "status": "finished",
      "utc_date": "2026-09-19T14:00:00.000Z",
      "home_team": { "id": "tm_1552", "name": "Brighton & Hove Albion" },
      "away_team": { "id": "tm_9145", "name": "Arsenal" },
      "score": {
        "home": 3,
        "away": 0,
        "regulation": { "home": 3, "away": 0 },
        "went_to_extra_time": false,
        "went_to_penalties": false,
        "winner": "home"
      },
      "xg_available": true,
      "shotmap_available": true
    }
  ],
  "meta": { "page": 1, "per_page": 1, "total": 561, "total_pages": 561 }
}
```

`score.winner` is `home`, `away` or `draw` once the match has finished, and counts extra time and penalties. `after_extra_time` and `penalty_shootout` are filled only when a match went that far.

## One day's matches in your time zone

Set `date_from` and `date_to` to the same day. Add `utc_offset` so "a day" means your local day, not the UTC one.

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.thestatsapi.com/api/football/matches?competition_id=comp_3039&date_from=2026-10-10&date_to=2026-10-10&utc_offset=%2B10:00&sort=utc_date" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const params = new URLSearchParams({
    competition_id: "comp_3039",
    date_from: "2026-10-10",
    date_to: "2026-10-10",
    utc_offset: "+10:00", // URLSearchParams encodes "+" as %2B for you
    sort: "utc_date",
  });
  const res = await fetch(`https://api.thestatsapi.com/api/football/matches?${params}`, {
    headers: { Authorization: `Bearer ${process.env.THESTATSAPI_API_KEY}` },
  });
  const { data } = await res.json();
  ```
</CodeGroup>

In UTC, the Premier League has 6 matches on 10 October 2026. At `+10:00` that day runs from 14:00 UTC on 9 October to 14:00 UTC on 10 October, so only Arsenal v Leeds United (11:30 UTC) comes back.

<Warning>
  Encode `+` as `%2B` in a raw URL. A bare `+` reads as a space and returns `400 BAD_REQUEST` ("Invalid utc\_offset"). Negative offsets such as `-05:00` need no encoding.
</Warning>

If you send `date` by mistake, the API tells you what to use instead:

```json theme={null}
{
  "error": {
    "code": "UNKNOWN_PARAMETER",
    "message": "Unknown query parameter 'date' (did you mean 'date_from' or 'date_to'?). Supported parameters: page, per_page, limit, competition_id, season_id, team_id, date_from, date_to, utc_offset, matchday, status, stage, group, sort.",
    "status_code": 400
  }
}
```

## A matchday, a group or a knockout round

<Tabs>
  <Tab title="League matchday">
    ```bash theme={null}
    curl "https://api.thestatsapi.com/api/football/matches?competition_id=comp_3039&season_id=sn_8406098&matchday=6" \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    Returns the 10 matches of Premier League 26/27 matchday 6.
  </Tab>

  <Tab title="Tournament group">
    ```bash theme={null}
    curl "https://api.thestatsapi.com/api/football/matches?competition_id=comp_6107&season_id=sn_326766&group=A&sort=utc_date" \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    Returns the 6 Group A matches of the 2022 World Cup. `group` needs `competition_id`, otherwise you get 400. Get the group letters from [List groups in a season](/docs/api-reference/competitions/groups).
  </Tab>

  <Tab title="Knockouts and play-offs">
    ```bash theme={null}
    curl "https://api.thestatsapi.com/api/football/matches?competition_id=comp_6107&season_id=sn_326766&stage=playoff" \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```

    `stage=playoff` returns knockout and play-off matches only (16 for the 2022 World Cup). `stage=regular` returns league and group matches only.
  </Tab>
</Tabs>

## Check which fixtures are loaded

A season's later rounds may not be loaded yet, so don't assume every fixture of the season is there. To see the furthest-ahead fixture that is loaded, ask for scheduled matches newest first:

```bash theme={null}
curl "https://api.thestatsapi.com/api/football/matches?competition_id=comp_3039&season_id=sn_8406098&status=scheduled&per_page=1" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The first row is the last loaded fixture, and `meta.total` is how many scheduled matches are loaded. [Get coverage for a competition](/docs/api-reference/coverage/league) shows finished and total matches per season. See [Coverage](/docs/concepts/coverage) for more.

## Get every page

Lists return 20 rows per page by default and 100 at most (`per_page=101` returns 400). Read `meta.total_pages` and request each page. Matches with the same kickoff are ordered by match ID, so pages stay stable.

```javascript JavaScript theme={null}
const headers = { Authorization: `Bearer ${process.env.THESTATSAPI_API_KEY}` };
const all = [];
for (let page = 1; ; page++) {
  const url = `https://api.thestatsapi.com/api/football/matches?competition_id=comp_3039&season_id=sn_8406098&per_page=100&page=${page}`;
  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(`Page ${page} failed with ${res.status}`);
  const { data, meta } = await res.json();
  all.push(...data);
  if (page >= meta.total_pages) break;
}
```

Each page is one request against your [rate limits](/docs/concepts/rate-limits), so cache results you don't need fresh.

## API reference

* [List matches](/docs/api-reference/matches/list): every filter and field
* [Get a match](/docs/api-reference/matches/get): venue, referee, half-time score
* [List groups in a season](/docs/api-reference/competitions/groups)
* [Get coverage for a competition](/docs/api-reference/coverage/league)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.