This guide provides the latest, exhaustive reference documentation for the football-data API. I revised this text for the 4th time now and maybe it still contains way too much prose, which not everybody likes. Good news is that you don’t need to read this guide from top to bottom, feel free to skip particular parts and jump directly to the sections that are of interest to you.

If you’re not in a hurry keep on reading. I try to point out design decisions and explain why the API ticks like it does.

Release notes

Almost 4 years after publishing the football-data API v2, today - the 20th of May 2022 - v4 sees light of day.

Within the last 2 years or so I did a couple of shadow-releases of a v3-version, which unfortunately never found it’s way to public. It had several improvements, but I didn’t find the time to write a proper documentation, so mostly I only gave the endpoints to clients asking for stuff not available in v2.

However, with 2021 ending, I decided to make some breaking changes and do a fresh v4 release and here we go. The main goals set for v4 were:

  • flatten data structures

  • improve consistency across resources

  • improve expressiveness

  • add control to response sizes by selectively unfolding specific nodes

  • review/rewrite entire documentation

  • remain as backward compatible as possible

I also used the upgrade to refactor code and upgrade to the latest versions of the software I use. Last but not least the API is more frontend-aware now, as I stumbled over several shortcomings while building native-stats.org on top of it, so I directly tackled them.

In the end I can say that I really like what I built, and I hope so do you.


Breaking changes that you have to take care of to migrate from v2:

  • The Player resource was renamed to Person as - surprisingly - there are coaches and referees as well, that do not fit well into a player resource.

  • The teams within the score node are only referenced by "home" and "away" (formerly: "homeTeam/awayTeam")

  • The score node now contains a regularTime attribute to indicate the result after 90 minutes in case of extra times or penalty shootouts.

  • Scores not available for particular match status are now optional.

  • Goals contain a score-node now that shows the score at this very moment of the match.

  • The captain node was removed from all responses, captains are not supported any more.

  • I dissolved most nestings and introduced flat data structures instead, e.g. a competition does not hold an area any more, but the response itself does. Thus client side mappings can be implementated much cleaner now.

  • When filtering by date ranges, elements from the specified dateTo-date are excluded now, e.g. &dateTo=2022-02-02 will contain matches only until and excluding the 2nd of February (list will contain matches until ending 1st February 00:00 UTC).

Changes that don’t affect upgrading:

Last, but not least some internal stuff:

  • Lifted Java platform to version 11 on all servers

  • Lifted the backend from Grails 3.x to 4.x

  • Lifted all servers to Debian Buster

  • Dockerized some external services

  • Moved server farm to new provider


Technical wording

Basically I use the terms Resource, Subresource and Filter to describe the API design. They are abstract "things" that can be combined in various combinations and forms to retrieve the data you need.

Resources are main building blocks of the API and most likely also appear as entities / domain classes in your application. Subresources on the other hand generally don’t make sense without the (Main) Resource they are based on. For example a standing always belongs to a Competition, so it’s dared to be a Subresource. Sometimes though the distinction cannot be made that cleanly, so some resources like Match appear as both: as Subresources (pre-filtered by it’s main resource) and as a sole Resource. Last but not least there are Filters to narrow down result sets. A Filter always describes an attribute and it’s value must be passed in an adequate format, which is declared by a Data Type. I usually describe these Data types using a loose regex-dialect.

Domain wording

A Competition represents a football league (e.g. Premiere League). It is defined by an id, a unique two to four-letter-code and has a type. It consists of Seasons, that hold a number of scheduled fixtures named Match. A certain number of Teams participate in one particular Season of a Competition.

I omitted to implement Season and Matchday as hierarchical elements by purpose. They are only attributes and can be used as Filters, but do not claim a separate resource for themselves to keep the design simple and data structures flat (I cannot emphasize the advantages of flat data structures enough). So you won’t find the typical round of other sports APIs, it doesn’t exist.

Last but not least a Team has a squad that represents the Persons playing for that very team.