Building with AI? Give your coding tool the whole reference in one file: https://soccer-data.co/llms.txt
SOCCER DATA Docs
Sign in Get API key
// Core concepts

Data model

The things in the API, their ids, their main fields and how they link together.

Everything in Soccer Data hangs off a few core things: competitions, their seasons, the matches in those seasons, and the teams and players who take part. This page explains each one, its id and the fields you'll use most.

IDs

Every id is a string made of two parts:

  • a word prefix that says what kind of thing it is, such as team_;
  • 12 lowercase letters and digits that say which one.

So Arsenal is team_f0ibhxdw7hs5 and the Premier League is competition_705uv6jm8myn.

Ids are permanent. A team, player or match keeps the same id for good, so you can store ids in your database, put them in config files, and use them in URLs of your own app. Look an id up once and reuse it.

Prefix What it names Example
competition_ A league, cup or tournament competition_705uv6jm8myn (Premier League)
season_ One season of a competition season_hr1ie7yrsdmt (Premier League 26/27)
team_ A club or national team team_f0ibhxdw7hs5 (Arsenal men)
player_ A player player_ul3vc6om97u5 (Bukayo Saka)
match_ A single match match_yoeml0e6ae37 (Arsenal v Leeds United)
shot_ One shot in a match's shot map shot_as8bbsa4f1mq
manager_ A manager, as home_manager or away_manager on a match manager_1dtehmda8rsp
referee_ A match referee referee_dxvcpogubown

A few rules make ids easy to work with:

  • Treat them as opaque strings. Don't parse the characters after the prefix or turn them into numbers; they carry no meaning.
  • Copy them exactly. Use the ids you get in our responses. An id we don't recognise, whether it has a typo or comes from another data source, returns 404 NOT_FOUND.
  • Find them by name when you need to. Find any ID shows every way to look them up.

How things connect

Competition
 └── Season
      └── Match ── home_team / away_team ── Team ── Player
  • A competition has many seasons. The competition's current_season_id points to the one running now.
  • A season has many matches. Each match carries its competition_id and season_id.
  • A match links to its two teams (home_team, away_team) and managers (home_manager, away_manager).
  • A player links to the team they play for now through current_team, which includes their jersey_number.
  • Teams and players also show up in season stats, lineups and match stats.

Groups in a tournament aren't separate things with their own ids. A match or table row simply carries a group_label, such as "A".

Competition

A league, a cup or a tournament.

Field Meaning
id, name The id and the name.
type league, cup or tournament.
country, country_code Where it's played. Both are null for international competitions.
subdivision_code The UK nation, such as GB-ENG. null outside the UK.
confederation For international competitions, such as UEFA or FIFA. null for domestic ones.
current_season_id The season running now. Returned when you fetch a single competition.

Season

One edition of a competition.

Field Meaning
id, name For example "Premier League 26/27".
year A label for display, such as 26/27 or 2026.
start_year, end_year Numbers you can sort by.
is_current true for the latest season.

Team

A club side or a national team.

Field Meaning
id, name, short_name The id and names.
country The team's country.
is_mens_team true, false, or null when unknown. Clubs often have a men's and a women's team with the same name.
primary_competition The id and name of the competition the team mainly plays in, or null. Useful to tell a first team from a youth side.

Player

Field Meaning
id, name, first_name, last_name The id and names.
position G, D, M or F, or an empty string when unknown.
date_of_birth, age YYYY-MM-DD and whole years. null when unknown.
nationality The country they represent.
height_cm Height, or null when not recorded.
current_team id, name and jersey_number at their current team.

Match

Field Meaning
id, competition_id, season_id The match and where it belongs.
status scheduled, live, finished, postponed or cancelled.
utc_date Kickoff, in ISO 8601 and always UTC.
matchday The league round. Often null in cups and knockouts.
stage_name The round in a knockout, such as quarter_final or final. null for regular league matches.
group_label The tournament group, or null.
home_team, away_team Each with an id and name.
score home and away are normal-time goals. For the overall result, read winner, and after_extra_time and penalty_shootout when present.
is_neutral true when neither side is at home. null means we don't know, not false.
live The match clock while it's in play, on the match list. null otherwise.

Availability flags

Some data only exists for some competitions or matches. These flags let you check before you spend a request:

Flag On Means
has_team_stats Competition Team stats exist in this competition.
has_player_stats Competition Player stats exist in this competition.
xg_available Competition, match Some xG data exists.
shotmap_available Match The shot map has shots with xG values.
xg_quality Match full for xG on every shot, otherwise none.
odds_available Competition, match Pre-match odds exist.
live_odds_available Competition, match In-play odds exist right now.

Flags on a competition describe the competition as a whole, not a particular season. For season-by-season answers, use the coverage endpoints.

Dates, times and nulls

  • Kickoff times are UTC. Convert them to your users' time zone when you display them.
  • Date filters take YYYY-MM-DD. To get matches in your own time zone's day, add utc_offset, such as -05:00. In URLs, write a plus sign as %2B (utc_offset=%2B02:00), or let URLSearchParams do it.
  • null always means "unknown" or "doesn't exist yet". It never stands for zero or false. For example, score.home is null before kickoff, live is null when a match isn't in play, and matchday is usually null in a cup (check stage_name).

Common requests

You want Ask for
A league table /competitions/{competition_id}/seasons/{season_id}/standings
A team's season /teams/{team_id}/stats?season_id=...
A player's season /players/{player_id}/stats?season_id=..., optionally with competition_id
A squad /teams/{team_id}/players
A women's team /teams?search=Arsenal&is_mens_team=false
One nation's competitions /competitions?country_code=GB-ENG; GB covers all UK nations
One day's matches /matches?date_from=...&date_to=... with the same date twice

Common mistakes

  • Converting ids to numbers or trimming the prefix. Keep them as the strings you received.
  • Mixing up teams with the same name. Check is_mens_team and primary_competition.
  • Reading null as zero. It means unknown.
  • Assuming is_neutral: null means a home game. It means we don't know.
  • Calling an optional endpoint without checking its flag. Missing data returns 404 or an empty data list.