Coverage by league
Every league uses the same endpoints and the same JSON. Change nfl to epl in the path and your parser keeps working. What differs is which fields a sport fills and which endpoints have data yet, and that’s what this page lists.
Anything listed under Not filled yet already has its endpoint or field: it answers with an empty list, null or 404, as noted. Code written against it today keeps working when the data arrives.
Leagues
Every plan includes all three. GET /v1/leagues lists the leagues your key can read.
The data model already covers basketball, baseball and hockey, but no league in those sports is served yet. A request for a league your key can’t read answers 403 with code forbidden.
What every game has
Everything in this table but injuries comes from the live game feed, so it’s there for every game in a live league and updates during the game. Game data arrives on the game’s stream as it changes; teams, players and injuries, which many games share, arrive on league:<alias>.
The Sample responses page has every one of these as a real, untrimmed response.
Stat keys
Box score lines are objects keyed by stat code inside a category. These are the codes you’ll see today:
NFL and NCAAF
Premier League
A player only has the categories and codes that apply to them, so treat every code as optional. New codes can appear; ignore the ones you don’t use.
Not filled yet
These endpoints and fields are part of the API, but nothing fills them today. Each applies to every league unless the row names one.
When any of these starts filling, it arrives the same way as everything else: over REST, and as changes on the stream.
How far back it goes
Statpad started collecting each league in November 2026. Earlier games and seasons aren’t backfilled, so the history you can read starts there, and there are no season-to-date totals from before it.
Once collected, a game stays readable:
- Over REST, for good. The game, its plays, drives, box score and roster stay available after it ends.
- As a change journal, for at least 7 days after it ends. That covers
GET /games/{id}/changesand resuminggame:<id>on the stream. A position older than what’s retained getsresync_required(a410over REST): read the game over REST instead. A league stream such asleague:nflcan be resumed for at least 30 days.
Corrections
A play or a stat line can change after it first appears, during the game and shortly after it, as the official record catches up. A correction arrives as an upsert with a higher version, and a play removed from the record arrives as a delete, on the same stream and in the same seq order as everything else. A game’s status moves to complete at the final whistle, but its stats can still be corrected after that.
If you store data, key it by id and keep the highest version you’ve seen. Then corrections need no special handling.