Race API
Every race, open to every agent.
The coach steve race index holds running and triathlon races worldwide: each edition's dates, every distance, climbing and descent, cut-offs, registration and price, and where it starts. Every fact comes from the race's own website and says when it was last confirmed.
It is free and read only. No account or key is needed. Reuse it under CC BY 4.0 with a link to each race's page.
Quick start
curl "https://getcoachsteve.com/api/races/v1/search?country=CA&distance=marathon&sort=date" curl "https://getcoachsteve.com/api/races/v1/races/berlin-marathon" curl "https://getcoachsteve.com/api/races/v1/races/berlin-marathon/2027?format=jsonld"
The full description is the OpenAPI 3.1 spec. Every answer is JSON, errors included, and carries its attribution and the race's page.
Endpoints
| Request | What it answers |
|---|---|
GET /search | Races matching the filters below. At least one filter; 25 a page at most (limit), 200 deep (offset); more says another page follows. sort: relevance, date, date_desc, distance, flattest. |
GET /races/{id} | One race by its id (rs_…), an edition's id (re_…) or its slug, with its next edition. An old slug answers redirect_to. |
GET /races/{id}/{year} | That year's edition. |
GET /counts | How many races the same filters match, split by country, month, distance, surface and entry. |
GET /changes | Races changed, merged or removed since since, oldest first, 500 a page, with next_cursor. Keep a copy in step without fetching it all again. |
GET /download/{file} | The whole index, rebuilt every night: races.jsonl, races.csv, races.jsonld, manifest.json. |
Filters
| Parameter | Values |
|---|---|
query | Words of the race's name, 120 characters at most. |
country | ISO 3166-1 alpha-2 code, such as CA or FR. |
region | A region or state code, such as CA-QC. |
distance | 5k, 10k, half, marathon, ultra, other |
surface | road, trail, track, mixed |
discipline | running, triathlon, duathlon, aquathlon, swimrun |
entry | qualifying, lottery, open |
certified | true for courses with a certification (AIMS and others). |
from, to | Dates (YYYY-MM-DD). from defaults to today; at most 800 days apart. |
lat, lng, radius_km | Races within radius_km (1 to 500) of a point; each carries distance_km. |
bbox | west,south,east,north in degrees. |
changed_since | Only races changed after this instant (ISO 8601). |
Fields and formats
fields=series.name,edition.start_date answers only those (each race's id and url always). format=jsonld answers the same facts as schema.org: a race is a SportsEvent in its EventSeries, each distance a subEvent, the entry an Offer; a search is an ItemList.
For AI agents
Connect an MCP client to https://getcoachsteve.com/mcp (Streamable HTTP, no sign-in). Two read-only tools:
| Tool | What it does |
|---|---|
search_races | The search's filters and sort, 10 races at most; count_only answers how many match. |
get_race | One race by id or slug, for a year if given. |
Every race page also reads as Markdown (ask with Accept: text/markdown) and carries the same facts as schema.org JSON-LD.
What the data means
Confirmed or expected. A date is confirmed when the race's official site states it and a second check or an independent source agrees. Otherwise it is expected, our estimate from the race's usual weekend, and marked so. verified_at is when the official site last confirmed it; stale says the next check is due.
Status. provisional, verified, conflict (the site changed a confirmed date; we are re-checking), cancelled, postponed, completed.
Places. coordinates_precision says whether a point is the race's own, its venue's, or only its city's.
Course. Climbing and descent are the organizer's stated figures or, where none is stated, worked out from the official course file.
Licence and limits
The data is free under CC BY 4.0. Credit it as “Race data by coach steve (getcoachsteve.com/races), CC BY 4.0” and link each race to its url.
Facts from sources whose terms do not allow republication never leave the index. Results and personal data are never collected.
Requests are limited to 120 a minute from one address. /v1 never breaks: a change that would is /v2, announced here first. Authentication: none (see auth.md).
Found a wrong fact? Email sam@palisade.email with the race's id; every race page also has “report an error”.
Changelog
1.1.0 · 2026-10-21
- format=jsonld: a race or a search as schema.org SportsEvents.
- /counts, /changes and /download/{file} (JSON Lines, CSV, JSON-LD and a manifest).
- Search takes bbox, changed_since and sort (relevance, date, date_desc, distance, flattest); a race near a point carries distance_km.
- fields on search and get.
1.0.0 · 2026-10-20
- /search, /races/{id} and /races/{id}/{year}, and the OpenAPI spec.