Season standings

Included in all plans

Season standings are available on all base plans (Starter, Growth, Pro, Enterprise) at no additional cost. Plans differ in the number of accessible leagues and hourly API call limits.

Compare plans β†’arrow-up-right

Quick summary: This tutorial covers the five standings endpoints available in API v3 (including by season, by round, live standings, and standing corrections) and shows how to enrich and filter them for real-world use in league tables and standings widgets.

What you'll learn:

  • How to retrieve standings by season, round, and live league ID

  • How to enrich standings responses with team names, league info, and detailed stats

  • How to use standing corrections for leagues with point deductions

  • How to select only the fields you need to reduce response size

Time to complete: 20 minutes Skill level: Beginner to Intermediate

Prerequisites: Authenticationarrow-up-right, Includesarrow-up-right, Leagues and Seasonsarrow-up-right

1. When to use this feature

Standings show the ranked table of teams competing in a season, including games played, wins, losses, goals scored, goals conceded, and total points. They update after each match and can be retrieved historically by round.

Real-world use cases

  • Use case 1: League table display You're building a football app and want to show the current Premier League table. GET Standings by Season ID returns the full ranked table for any season, enrichable with team names and detailed statistics.

  • Use case 2: Historical round-by-round standings You want to show how a team's position changed over the course of a season. GET Standings by Round ID lets you retrieve the table as it stood at any specific round.

  • Use case 3: Live league table during an active match You want the table to update in real time while matches are being played. GET Live Standings by League ID returns the current in-progress standings for any active season.

  • Use case 4: Displaying point deductions A club receives a disciplinary sanction mid-season. GET Standing Corrections by Season ID provides the deduction data so you can accurately reflect the adjusted table.

When NOT to use this feature

❌ Player rankings or top scorers : Use the Topscorersarrow-up-right endpoint for individual player standings.

❌ Expected points tables (xPTS) : Use the Expected Goals (xG)arrow-up-right tutorial for expected-points-based standings.

2. How to retrieve data

Understanding the endpoints

Base URL:

Available endpoints:

Endpoint
Path suffix
Description

GET All Standings

(base URL)

All standings in your subscription

GET Standings by Season ID

/seasons/{season_id}

Full league table for a specific season

GET Standings by Round ID

/rounds/{round_id}

Table as it stood at a specific round

GET Standing Corrections by Season ID

/corrections/seasons/{season_id}

Point deductions for a season

GET Live Standings by League ID

/live/leagues/{league_id}

Real-time table for an active season

Available parameters:

Parameter
Type
Required
Description
Example

api_token

string

Yes

Your API authentication token

YOUR_API_TOKEN

include

string

No

Related data to attach

participant;league;details.type

select

string

No

Fields to return on includes

participant:name;league:name

filters

string

No

Filter by specific fields

standingSeasons:19686

Step-by-step implementation

Step 1: GET Standings by Season ID

This is the most commonly used standings endpoint. Pass the season_id for the season you want.

For example, the Danish Superliga 2022/2023 season (season ID: 19686):

JavaScript:

Step 2: GET Standings by Round ID

Returns the league table as it stood at a specific round, useful for historical analysis or "table at round N" features. You need the round_id, which you can retrieve from the Rounds by Season ID endpointarrow-up-right.

Step 3: GET Live Standings by League ID

Returns the current in-progress table for an active season. Note that this endpoint takes a league_id, not a season_id, because you can only retrieve live standings for a currently active season.

circle-info

The response will be empty if the league has no active season or no matches are currently being played in that league.

Step 4: GET Standing Corrections by Season ID

Returns point deductions applied to teams in a given season. Use this alongside the main standings to accurately display adjusted positions.

Step 5: Adding includes

By default, standings return only IDs (participant ID, league ID, etc.) and not names. Use include to attach readable data.

The most useful includes for standings:

  • participant : Team name, logo, country, and venue

  • league : League name and logo

  • details.type : Detailed stats per team (matches played, wins, goals, form, etc.)

circle-exclamation

Step 6: Selecting specific fields

Use select on includes to return only the fields you need, reducing response size significantly.

Step 7: Complete example

3. Working with the data

Understanding the response structure

Key fields:

Field
Type
Description

id

integer

Unique standing record ID

participant_id

integer

The team's ID, use with include=participant to get the name

position

integer

Current league position

result

string

Position change: "up", "down", or "equal"

points

integer

Total points accumulated

round_id

integer

The most recent round this standing reflects

standing_rule_id

integer

The tiebreaker rule applied at this position

With include=details.type, each team object gains a details array where each entry represents a stat (matches played, wins, goals for, etc.) identified by type_id.

Processing the data

Build a sorted league table with team names:

Extract a specific stat from details (e.g. matches played, type_id 129):

4. Common pitfalls

Pitfall 1: Using GET All Standings instead of by Season ID

GET All Standings returns every standing across every league in your subscription (thousands of records). Always use GET Standings by Season ID for a specific table.

Pitfall 2: Including .type on every request

Including details.type on standings triggers a type resolution for every stat on every team. This is expensive at scale.

Pitfall 3: Using live standings for historical data

GET Live Standings only works for currently active seasons. For historical or completed season data, use GET Standings by Season ID.

Pitfall 4: Not handling group standings (cup competitions)

In cup competitions and leagues with group stages, standings are returned per group. Always check group_id in the response and handle both cases.

5. Advanced usage

Advanced technique 1: Round-by-round position tracking

Show a team's position across every round of the season to visualise their trajectory.

Advanced technique 2: Combining standings with fixtures for a match-day view

On a match day, show the current table alongside the day's fixtures so users can see what's at stake.

6. Common errors

401 Unauthorised

Cause: Missing or invalid api_token. Fix: Confirm the token is correct and present on every request. Find it at MySportmonksarrow-up-right.

404 Not Found

Cause: The season_id or round_id does not exist or belongs to a league outside your subscription. Fix: Use GET All Seasons to verify the season ID, or check the ID Finderarrow-up-right.

429 Too Many Requests

Cause: Too many requests within your hourly limit. Fix: Cache standings (they only change after each matchday). See the Rate Limiting guidearrow-up-right.

Empty data array from live standings

Cause: The league has no active season, or no matches are currently being played. Fix: Fall back to GET Standings by Season ID using the currentSeason ID retrieved from the leagues endpoint.

See also

Prerequisites

Related data

Optimisation

Related endpoints

FAQ

Q: How do I find the season ID for a league?

Use the leagues endpoint with include=currentSeason to get the active season ID, or include=seasons for all historical seasons. See the Leagues tutorialarrow-up-right.

Q: How often are standings updated?

Standings update after each processed match. During an active match day, they reflect completed fixtures only. Use GET Live Standings to see in-progress positions.

Q: How do I handle leagues with group stages, like the UEFA Champions League?

Group-stage standings include a non-null group_id. Group results into separate tables by group_id before rendering.

Q: What does result: "equal" mean on a standing row?

It means the team's position did not change since the last update. "up" means they gained positions; "down" means they dropped.

Q: Are standings available on all plans?

Yes. All plans include standings access for their covered leagues.

Best practices summary

βœ… DO:

  • Use GET Standings by Season ID as your primary standings endpoint

  • Use select on includes to return only the fields you need

  • Cache standings, they only change after each matchday

  • Retrieve types once from the Types endpoint and cache them rather than including .type

  • Handle group_id to support cup competitions and group stages

❌ DON'T:

  • Use GET All Standings, always scope to a season or round

  • Include .type in production requests

  • Use live standings for historical or completed seasons

  • Assume all leagues have a single-table format

Last updated

Was this helpful?