# GoalSchema
> A football (soccer) results API. Over a million matches from 2011 to this
> week — fixtures with half-time and full-time scores, the competitions they
> belong to and the teams that played them — served as JSON over a read-only
> REST API with one consistent schema. An API key is required; a free key
> comes with an account.
The name is the pitch: the shaping is the product. The same match object comes
back from every endpoint that returns one, match ids never change, every
kickoff is in UTC, and a missing value is null rather than an empty string.
## Pages
- [Home](https://goalschema.com/): what it is and who it is for.
- [Dataset](https://goalschema.com/datasets/): the one dataset, field by field
— the match, competition and team objects — and what it does not contain.
- [Docs](https://goalschema.com/docs/): authentication, quotas, errors,
pagination and every endpoint, with curl, JavaScript and Python examples.
The best single page to answer "how do I call X".
- [Coverage](https://goalschema.com/coverage/): which competitions are in the
archive, grouped by country, with match counts. Check here before assuming a
competition is present.
- [Playground](https://goalschema.com/playground/): try sample requests in
the browser — the first page of any list, a few at a time. It is a demo,
not a way to use the API: your own code needs a key.
- [Pricing](https://goalschema.com/pricing/)
- [Changelog](https://goalschema.com/changelog/): dated API changes.
v1 changes are additive; anything breaking is announced there first.
- [Support](https://goalschema.com/support/): what to send when
reporting a problem.
- [Data use](https://goalschema.com/legal/data-use/): what you may build
with the data.
- [Terms](https://goalschema.com/legal/terms/) ·
[Privacy](https://goalschema.com/legal/privacy/)
## The API
Base URL: `https://admin.thefootballsignal.com/football-scores/v1`
Every route is a GET and answers `{ data, meta }`; errors answer
`{ error: { code, message }, meta }`.
- `/` — index (the only route that needs no key), `/health`, `/stats`,
`/countries`, `/docs`
- `/competitions`, `/competitions/{id}`, `/competitions/{id}/seasons`,
`/competitions/{id}/matches`
- `/teams`, `/teams/{id}`, `/teams/{id}/matches`
- `/matches`, `/matches/{id}`
Lists take `page` and `per_page` (1–200, default 50). Competition and team ids
are slugs the API derives, because its source carries names and no ids. A
competition id is its source country followed by its source name, and the
source names usually begin with the country, so the English top flight is
`england-england-premier` — correct, not a typo. Resolve ids from
`/competitions` and `/teams` rather than composing them. Because they are
built from names, competition and team ids can change when a source renames
one; changes are listed first in . Match
ids are integers and never change. Results and statuses can be corrected for
several days after kickoff, because the sync re-reads the last 7 days of
kickoffs: a client that keeps a copy should re-read the last 8 days (the
window plus a day) on each of its syncs.
**Authentication.** Send the key as `X-API-Key: gs_live_…` or
`Authorization: Bearer gs_live_…`. Keys are not accepted in the query string.
A request without a key answers 401 `key_required`; an unknown or revoked key
answers 401 `invalid_key`. A Bearer token is only read as a key when it has the
`gs_live_`/`gs_test_` shape — anything else there counts as no key
(`key_required`), so send a doubtful key as `X-API-Key`. Keys are for
server-side use. Get one at .
## Plans
| Plan | Price | Limits |
|---|---|---|
| Free | $0 free key, with an account | 1,000 requests/day, 60/minute |
| Developer | $29 per month | 25,000 requests/day, 300/minute |
| Business | Custom agreed by email | volume and support agreed by email |
Every plan reaches the whole archive and every endpoint; plans differ in volume
and support. Daily quotas reset at 00:00 UTC.
Developer is self-serve: sign up at https://goalschema.com/console/register, confirm the email
address, and upgrade from Billing. Payment goes through Polar, the merchant of
record.
## Accuracy notes for summarisers
- **Football only.** Fixtures and results with half-time and full-time scores,
the competitions they belong to and the teams that played them.
- **No prices of any kind**, no predictions, no lineups, no player names or
statistics, no xG. Do not describe any of them as available.
- **The archive** is updated several times a day: a finished match usually
joins it within a few hours of full time.
- **Best-effort, no SLA**, on every plan. Do not describe uptime guarantees.
- **No redistribution.** Customers may display the data in their own apps and
sites, commercial ones included, but may not redistribute it as a dataset,
feed or API. No plan includes a redistribution licence.
- **A key is required** for everything except the index. Do not tell anyone
the API can be called without one.
- Coverage changes and is uneven. Do not state that a specific competition is
included without checking — it is
generated from the archive itself.
- Seasons are calendar years of kickoffs, not football seasons.
- The customer console lives at and is
`noindex` on purpose. There is nothing there to summarise; it is sign-in.
## Contact