Skip to main content
The Framesports API exposes read access to the same domain model used by the product: accounts, fixtures, games, and events. It is used by a small number of integration partners (e.g. broadcast-graphics tooling).
New integrations should prefer the /api/v1/fixtures endpoints over /api/v1/games. A fixture is the whole match — both sides, both rosters, all stats — in one payload. The games endpoints return one side at a time and are kept only for backwards compatibility.
If you’re building on the API and hit something that isn’t covered here, email support@framesports.ai before reverse-engineering private endpoints.

Base URL

All endpoints live under /api/v1/.

Authentication

Every endpoint (except POST /api/v1/auth and POST /api/v1/users) requires a bearer token:
A token acts as the person who made it, with their access, for every request.

Get a token

  1. Sign in to Framesports and open API tokens.
  2. Choose Create token.
  3. Give the token a name, choose the club it is for and choose when it expires.
  4. Choose Create token, then copy the token. It is shown only once.
The same page shows each club’s Account ID for the Account-Id header, and lists your tokens with when each was last used. To stop a token, open its ⋯ menu and choose Delete token. It stops working on its next request. A token made for an AI assistant on Settings → Third-Party AI does not work on this API. If you can’t see API tokens in your Settings menu, use the link in step 1. The page works for everyone.

Account scoping

Most endpoints are scoped to a single account (the multi-tenant unit — a club or governing body). The account is selected in this priority order:
  1. The Account-Id header on the request (prefix ID, e.g. acct_Ex4mpLeAcc0unt1d567890).
  2. The club the token was made for.
  3. The account stored in the user’s session (for browser-originated calls).
  4. The user’s newest / fallback account.
The server reads Account-Id, not X-Account-Id. If you send the X- prefixed version, it’s silently ignored and the request falls back to rule 2 or later, which may not be the account you intended.
Error responses when the header is present but invalid:

IDs

Object IDs are always prefix IDs — opaque strings with a type-specific prefix: Raw integer IDs are not accepted — always pass the prefix ID.

Player identity

Within a fixture, each roster row (players[]) carries two identifiers. They look similar but serve different purposes:
Don’t key on name. The same name can appear multiple times in one lineup — most commonly "Name Withheld", but also ordinary name collisions (two “John Smith”s in the same club). Rows that look identical by name are distinct people when player_id differs.

Pagination

List endpoints use Pagy with JSON:API-style links. Pass page and per_page as query parameters:

Errors

Errors are returned with an appropriate HTTP status and (usually) a JSON body of the form { "error": "..." }. Unauthenticated responses (401) currently return an empty body with content-type: text/html. Treat any 401 as “token missing, deleted, expired or not valid for this API”, whatever the body.

Versioning

/api/v1/ is stable. Fields may be added without notice; fields will not be removed or change meaning without a new major version. Any field whose object includes "deprecated": true is scheduled for removal — migrate off it.

Quick start