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

# Canonical IDs

> uniqueTournament.id vs tournament.id — which to store, which to query, and how to avoid season-rollover breakage

## The dual-ID model

Every Football V2 competition is identified by **two** numeric IDs that look interchangeable but are not. `uniqueTournament.id` is the **canonical, season-independent identifier** for a league or competition. `tournament.id` is a **per-season, per-group variant** that changes every year and is only meaningful when paired with a `seasonId`.

Mixing them up is the single most common cause of broken integrations — IDs that worked last season silently stop resolving when the new season rolls over.

***

## Side-by-side

| Field                 | Scope                                          | Stable across seasons?    | Use for                                                                           |
| --------------------- | ---------------------------------------------- | ------------------------- | --------------------------------------------------------------------------------- |
| `uniqueTournament.id` | League / competition (e.g. "Premier League")   | ✅ Yes — never changes     | Storage, filtering, image lookup, cross-season queries                            |
| `tournament.id`       | A specific season + group within a competition | ❌ No — regenerated yearly | Only as a parameter to season-scoped endpoints (standings, top scorers, brackets) |

## Worked example

A trimmed `/api/event/{id}` response shows both fields side by side:

```json theme={null}
{
  "event": {
    "id": 12436891,
    "tournament": {
      "id": 1,
      "name": "Premier League 25/26",
      "uniqueTournament": {
        "id": 17,
        "name": "Premier League",
        "category": { "id": 1, "name": "England", "alpha2": "EN" }
      }
    },
    "season": { "id": 76986, "name": "Premier League 25/26", "year": "25/26" }
  }
}
```

* `tournament.uniqueTournament.id = 17` → store this. It will still be `17` in 2030.
* `tournament.id = 1` → never store this. Next season it's a different number.
* `season.id = 76986` → discover dynamically via `/api/tournaments/17/seasons` whenever you need season-scoped data.

***

## Confirmed canonical IDs (top competitions)

| Competition           | `uniqueTournament.id` |
| --------------------- | --------------------- |
| Premier League        | **17**                |
| LaLiga                | **8**                 |
| Bundesliga            | **35**                |
| Serie A               | **23**                |
| Ligue 1               | **34**                |
| UEFA Champions League | **7**                 |
| UEFA Europa League    | **679**               |
| FA Cup                | **19**                |
| MLS                   | **242**               |
| FIFA World Cup        | **16**                |

<Tip>
  If you've seen a different ID for one of these in the wild (e.g. `49` for FA Cup, `1` for Premier League, `104` for MLS), you were looking at the per-season `tournament.id`, not the canonical one.
</Tip>

***

## When to use which

**Use `uniqueTournament.id` when:**

* Storing a competition reference in your database
* Filtering matches, fixtures, or teams by competition
* Loading a league logo via `/images/tournaments/{id}`
* Querying competition-level metadata that doesn't depend on the current season

**Use `tournament.id` (paired with `seasonId`) only when:**

* Calling season-scoped endpoints such as:
  * `/api/tournament/{tournamentId}/season/{seasonId}/standings`
  * `/api/tournament/{tournamentId}/season/{seasonId}/top-players/...`
  * `/api/tournament/{tournamentId}/season/{seasonId}/cuptrees`

And in those cases, **resolve `tournament.id` and `seasonId` dynamically every time** — don't cache them past a single season.

## Resolution flow

```
Have:    uniqueTournament.id (e.g. 17 for Premier League)
   │
   ▼
GET /api/tournaments/17/seasons   ← discover current seasonId
   │
   ▼
seasonId (e.g. 76986)
   │
   ▼
GET /api/tournament/{tournamentId}/season/{seasonId}/standings
```

The `tournamentId` for the season-scoped call comes from the same seasons response — never hardcode it.

***

## Anti-pattern

<Warning>
  **Never persist `tournament.id` as a foreign key.** It will silently break at the next season rollover when SportsAPI Pro regenerates per-season IDs. Every integration that hits us with "the league suddenly stopped working in August" has done exactly this.
</Warning>

## Related

* [Tournament endpoints reference](/api-reference/football-v2/tournament)
* [Search endpoint](/api-reference/search/search) — discover `uniqueTournament.id` by name
* [One-Time ID Migration Guide](/api-reference/guides/id-migration)
* [Image endpoint troubleshooting](/api-reference/images)
