Season standings
Standings are published per season rather than computed from results. That is deliberate: a table derived purely from match scores will disagree with the official one whenever a points deduction, an awarded result, or an expunged record applies — and it will disagree silently.
Tiebreakers also vary by competition. The Premier League orders on goal difference; La Liga resolves ties on head-to-head record first. Reading the published standing avoids reimplementing each competition's rulebook.
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/football/competitions/{competition_id}/seasons/{season_id}/standings | Ranked table for one season. |
| GET | /api/v1/football/teams/{team_id}/standings | Current-season positions for one team. |
Worked example: finding a season and its table
Competition and season identifiers are Stats API values, not upstream ones. Resolve a name to an ID once, store the ID, and use it in later requests — that is what keeps an integration stable across a provider change.
GET /api/v1/football/competitions?q=premier%20league&limit=5
Authorization: Bearer sapi_live_...
{
"data": [
{ "id": "comp_4f2a91c7de03", "name": "Premier League",
"country_name": "England", "type": "league", "season_count": 17 }
],
"meta": { "page": 1, "limit": 5, "total": 1 }
}
GET /api/v1/football/competitions/comp_4f2a91c7de03/seasons
{
"data": [
{ "id": "season_31a7c0d94b26", "name": "2026",
"is_current": true, "team_count": 20, "match_count": 380 }
]
}
Standing field semantics
| Field | Type | Meaning |
|---|---|---|
| position | integer | Rank within the group, applying the competition's own tiebreakers. |
| group | string or null | Group label for competitions with a group stage; null for a single table. |
| played / won / drawn / lost | integer | Matches counted toward this standing. |
| goals_for / goals_against | integer | Goals in counted matches. |
| goal_difference | integer | Convenience field: goals_for minus goals_against. |
| points | integer | Includes any deduction the competition has applied. |
| form | string or null | Recent results, most recent last, where the source supplies it. |
| description | string or null | Qualification or relegation note, e.g. Champions League. |
Things that surprise integrators
| Situation | What to expect |
|---|---|
| A season shows is_current false for every season | Correct for archived datasets. Do not assume exactly one current season exists. |
| season_count is high but few have data | The catalog lists seasons the source knows about; coverage varies per season. |
| Standings are empty for a covered competition | Group-stage or cup formats may have no table. Check the coverage flag rather than inferring failure. |
| Points do not match played results | A deduction or awarded result has been applied. The published standing is authoritative. |
Available operations
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/football/competitions | Paginated competition catalog. |
| GET | /api/v1/football/competitions/{competition_id} | One competition by Stats API public ID. |
| GET | /api/v1/football/competitions/{competition_id}/seasons | Seasons belonging to a competition. |
Collection filters
The collection accepts q for a case-insensitive name search plus page and limit for pagination. Limit defaults to 25 and is capped at 100.
GET /api/v1/football/competitions?q=premier&page=1&limit=25
Public IDs
Persist the public competition_id in your own records. Identical imports keep it unchanged. Do not infer an ID from a name or slug; ambiguous corrections or a provider migration without an approved mapping may require a new resource ID.