{"openapi":"3.1.0","info":{"title":"DEKA Results API","description":"One stable data model for Spartan DEKA race data across years, countries, formats and timing providers.\n\nEvery response is `{data, meta, errors}`. Lists page with an opaque `cursor`; pass the `meta.cursor` from one response as `?cursor=` on the next. Durations are integer milliseconds (`*_ms`) with a rendered string beside them; the timing provider's own string is kept as `source_finish_time` so a value is always auditable.\n\n`meta.last_updated_at`, `meta.source_count` and `meta.is_provisional` tell you how fresh and how settled a payload is. A result with no splits returns `splits: []` — we never estimate a split a timing provider did not publish.\n\nSend an API key as `X-API-Key` or `Authorization: Bearer`. Unauthenticated reads are permitted at a low rate so the public site can call this API directly.","license":{"name":"proprietary","identifier":"proprietary"},"version":"1.0.0"},"paths":{"/v1/account/keys":{"get":{"tags":["account"],"summary":"Your API keys","description":"List keys, or `POST` to create one. The secret is returned exactly once, on creation.","parameters":[],"responses":{}}},"/v1/account/login":{"post":{"tags":["account"],"summary":"Sign in","description":"Returns a session token.","parameters":[],"responses":{}}},"/v1/account/logout":{"post":{"tags":["account"],"summary":"Sign out","description":"Idempotent.","parameters":[],"responses":{}}},"/v1/account/me":{"get":{"tags":["account"],"summary":"Your account","description":"Plan, effective rate limit, and which capabilities that plan includes.","parameters":[],"responses":{}}},"/v1/account/plans":{"get":{"tags":["account"],"summary":"Plans and capabilities","description":"The plan ladder, generated from the same table the API gates on — so it cannot advertise something the API refuses.","parameters":[],"responses":{}}},"/v1/account/register":{"post":{"tags":["account"],"summary":"Create an account","description":"Returns a session token. Store it in an httpOnly cookie; it is not an API key and the data routes will not accept it.","parameters":[],"responses":{}}},"/v1/account/usage":{"get":{"tags":["account"],"summary":"Your usage","description":"Requests, errors and rate-limited responses for the last 30 days, per day.","parameters":[],"responses":{}}},"/v1/athletes/search":{"get":{"tags":["athletes"],"summary":"Search athletes","description":"Name search across canonical athletes.","parameters":[{"name":"q","in":"query","description":"Search term, at least 2 characters.","required":false},{"name":"limit","in":"query","description":"Default 25, maximum 100.","required":false}],"responses":{}}},"/v1/athletes/{id}":{"get":{"tags":["athletes"],"summary":"Get an athlete","description":"One athlete with personal bests per format.","parameters":[{"name":"id","in":"path","description":"Athlete UUID.","required":true}],"responses":{}}},"/v1/athletes/{id}/results":{"get":{"tags":["athletes"],"summary":"An athlete's career","description":"Every result we hold for this athlete, across formats and years, newest first.","parameters":[{"name":"id","in":"path","description":"Athlete UUID.","required":true}],"responses":{}}},"/v1/events":{"get":{"tags":["events"],"summary":"List events","description":"DEKA events, newest first. Cursor-paginated.","parameters":[{"name":"country","in":"query","description":"ISO 3166-1 alpha-2 country code, e.g. `US`.","required":false},{"name":"from","in":"query","description":"Only events starting on or after this date (YYYY-MM-DD).","required":false},{"name":"to","in":"query","description":"Only events starting on or before this date (YYYY-MM-DD).","required":false},{"name":"format","in":"query","description":"Only events containing a race of this format, e.g. `FIT`, `MILE`, `STRONG`.","required":false},{"name":"status","in":"query","description":"`scheduled`, `live`, `completed`, `cancelled` or `unknown`.","required":false},{"name":"season","in":"query","description":"Calendar season, e.g. `2026`.","required":false},{"name":"q","in":"query","description":"Substring match on the event name.","required":false},{"name":"cursor","in":"query","description":"Opaque cursor from a previous response's `meta.cursor`.","required":false},{"name":"limit","in":"query","description":"Page size. Default 50, maximum 200.","required":false}],"responses":{}}},"/v1/events/{id}":{"get":{"tags":["events"],"summary":"Get an event","description":"One event with its races, contributing sources and the filter facets actually present in its results. Accepts a UUID or a slug.","parameters":[{"name":"id","in":"path","description":"Event UUID or slug.","required":true}],"responses":{}}},"/v1/events/{id}/results":{"get":{"tags":["results"],"summary":"List an event's results","description":"Results across every competition at an event, fastest first; untimed results (DNF/DNS/DQ) sort last. Cursor-paginated.","parameters":[{"name":"id","in":"path","description":"Event UUID or slug.","required":true},{"name":"race","in":"query","description":"Restrict to one race (UUID from the event payload).","required":false},{"name":"format","in":"query","description":"Restrict to one format, e.g. `FIT`.","required":false},{"name":"division","in":"query","description":"`elite`, `age_group`, `open`, `youth`, `ruck`, `masters`, `team`.","required":false},{"name":"gender","in":"query","description":"`male`, `female` or `mixed`.","required":false},{"name":"age_group","in":"query","description":"Age-group label as published.","required":false},{"name":"search","in":"query","description":"Substring match on the athlete or team name.","required":false},{"name":"cursor","in":"query","description":"Opaque cursor from a previous response's `meta.cursor`.","required":false},{"name":"limit","in":"query","description":"Page size. Default 50, maximum 200.","required":false}],"responses":{}}},"/v1/formats":{"get":{"tags":["meta"],"summary":"List formats","description":"Every DEKA format we recognise, with the number of races currently classified under it. Formats are an open vocabulary: new ones appear here without an API change.","parameters":[],"responses":{}}},"/v1/health":{"get":{"tags":["meta"],"summary":"Service health","description":"Row counts, the last ingestion run and the sources enabled in this deployment.","parameters":[],"responses":{}}},"/v1/leaderboards":{"get":{"tags":["leaderboards"],"summary":"Global leaderboard","description":"The most recent snapshot matching the filters. Snapshots are kept rather than overwritten, so rankings remain answerable as of a point in time.","parameters":[{"name":"season","in":"query","description":"Calendar season, e.g. `2026`.","required":false},{"name":"format","in":"query","description":"`FIT`, `MILE`, `STRONG`, `ATLAS`, `FIRE`, ...","required":false},{"name":"division","in":"query","description":"Division as published.","required":false},{"name":"gender","in":"query","description":"`male`, `female` or `mixed`.","required":false},{"name":"age_group","in":"query","description":"Age-group label as published.","required":false},{"name":"limit","in":"query","description":"Default 100, maximum 500.","required":false},{"name":"offset","in":"query","description":"Rank offset.","required":false}],"responses":{}}},"/v1/percentile":{"get":{"tags":["insights"],"summary":"Percentile lookup","description":"**Pro.** Where a finish time ranks among every comparable result we hold. Pass a time as `34:59.9` or as `time_ms`, then narrow the cohort as much or as little as you like.","parameters":[{"name":"format","in":"query","description":"Required. `FIT`, `MILE`, `STRONG`, `ATLAS`, ...","required":false},{"name":"time","in":"query","description":"Finish time as published, e.g. `34:59.9` or `0:34:33`.","required":false},{"name":"time_ms","in":"query","description":"The same time in milliseconds, if you already have it.","required":false},{"name":"gender","in":"query","description":"`male`, `female` or `mixed`.","required":false},{"name":"age_group","in":"query","description":"Age-group label as published.","required":false},{"name":"division","in":"query","description":"`elite`, `age_group`, `open`, `youth`, `ruck`, ...","required":false},{"name":"season","in":"query","description":"Restrict the cohort to one season.","required":false}],"responses":{}}},"/v1/races/{id}/zone-stats":{"get":{"tags":["insights"],"summary":"Field zone statistics","description":"**Scale.** Median, mean, quartiles and count per zone across a whole race field, optionally sliced by gender, age group or division. Needs at least 10 finishers with published splits; below that it answers `409` rather than a meaningless median.","parameters":[{"name":"id","in":"path","description":"Race UUID, from an event payload.","required":true},{"name":"gender","in":"query","description":"`male`, `female` or `mixed`.","required":false},{"name":"age_group","in":"query","description":"Age-group label as published.","required":false},{"name":"division","in":"query","description":"Division as published.","required":false}],"responses":{}}},"/v1/results/{id}":{"get":{"tags":["results"],"summary":"Get a result","description":"One result with its event, race, splits and, for a team result, its members. `splits` is always present; it is an empty array when no timing provider published them.","parameters":[{"name":"id","in":"path","description":"Result UUID.","required":true}],"responses":{}}},"/v1/results/{id}/pacing":{"get":{"tags":["insights"],"summary":"Pacing report","description":"**Pro.** One race taken apart: how the clock split between zones and runs, how much the runs faded from the first half to the second, and every segment measured against the median for the same segment in the same race.","parameters":[{"name":"id","in":"path","description":"Result UUID.","required":true}],"responses":{}}}},"components":{"schemas":{"ApiError":{"type":"object","required":["title","status"],"properties":{"detail":{"type":["string","null"]},"status":{"type":"integer","format":"int32","minimum":0},"title":{"type":"string"}}},"AthleteDto":{"type":"object","required":["id","display_name","result_count"],"properties":{"country_code":{"type":["string","null"]},"display_name":{"type":"string"},"first_name":{"type":["string","null"]},"first_race_date":{"type":["string","null"],"format":"date"},"gender":{"type":["string","null"]},"home_town":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"last_name":{"type":["string","null"]},"last_race_date":{"type":["string","null"],"format":"date"},"personal_bests":{"type":["array","null"],"items":{"$ref":"#/components/schemas/PersonalBestDto"}},"result_count":{"type":"integer","format":"int32"}}},"EventDto":{"type":"object","required":["id","slug","name","status","is_provisional","result_count","last_updated_at"],"properties":{"city":{"type":["string","null"]},"country":{"type":["string","null"]},"country_code":{"type":["string","null"]},"end_date":{"type":["string","null"],"format":"date"},"facets":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/FacetsDto"}]},"id":{"type":"string","format":"uuid"},"is_provisional":{"type":"boolean"},"last_updated_at":{"type":"string","format":"date-time"},"latitude":{"type":["number","null"],"format":"double"},"longitude":{"type":["number","null"],"format":"double"},"name":{"type":"string"},"races":{"type":["array","null"],"items":{"$ref":"#/components/schemas/RaceDto"}},"region":{"type":["string","null"]},"result_count":{"type":"integer","format":"int32"},"season":{"type":["integer","null"],"format":"int32"},"slug":{"type":"string"},"sources":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SourceRefDto"}},"start_date":{"type":["string","null"],"format":"date"},"status":{"type":"string"},"timezone":{"type":["string","null"]},"venue":{"type":["string","null"]}}},"EventRefDto":{"type":"object","required":["id","slug","name"],"properties":{"country_code":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"slug":{"type":"string"},"start_date":{"type":["string","null"],"format":"date"}}},"FacetsDto":{"type":"object","required":["divisions","genders","age_groups"],"properties":{"age_groups":{"type":"array","items":{"type":"string"}},"divisions":{"type":"array","items":{"type":"string"}},"genders":{"type":"array","items":{"type":"string"}}}},"FormatDto":{"type":"object","required":["code","name","family","is_team","race_count"],"properties":{"code":{"type":"string"},"family":{"type":"string"},"is_team":{"type":"boolean"},"name":{"type":"string"},"race_count":{"type":"integer","format":"int64"}}},"HealthDto":{"type":"object","required":["status","version","events","races","results","splits","athletes","leaderboard_entries","enabled_sources"],"properties":{"athletes":{"type":"integer","format":"int64"},"enabled_sources":{"type":"array","items":{"type":"string"}},"events":{"type":"integer","format":"int64"},"last_ingest_at":{"type":["string","null"],"format":"date-time"},"last_ingest_status":{"type":["string","null"]},"leaderboard_entries":{"type":"integer","format":"int64"},"races":{"type":"integer","format":"int64"},"results":{"type":"integer","format":"int64"},"splits":{"type":"integer","format":"int64"},"status":{"type":"string"},"version":{"type":"string"}}},"LeaderboardEntryDto":{"type":"object","required":["rank","athlete_name","season","format"],"properties":{"age_group":{"type":["string","null"]},"athlete_id":{"type":["string","null"],"format":"uuid"},"athlete_name":{"type":"string"},"best_time":{"type":["string","null"]},"best_time_ms":{"type":["integer","null"],"format":"int32"},"country_code":{"type":["string","null"]},"division":{"type":["string","null"]},"format":{"type":"string"},"gender":{"type":["string","null"]},"rank":{"type":"integer","format":"int32"},"season":{"type":"integer","format":"int32"}}},"Meta":{"type":"object","properties":{"count":{"type":["integer","null"],"minimum":0},"current_plan":{"type":["string","null"],"description":"The plan this answer was served under, so a client can tell a gated-down payload from\na complete one without guessing."},"cursor":{"type":["string","null"],"description":"Opaque cursor for the next page. Absent when there is none."},"has_more":{"type":["boolean","null"]},"is_provisional":{"type":["boolean","null"]},"last_updated_at":{"type":["string","null"],"format":"date-time","description":"When the underlying records were last written. Callers should not have to guess how\nfresh a dataset is."},"source_count":{"type":["integer","null"],"description":"How many independent sources contributed to this payload.","minimum":0}}},"PersonalBestDto":{"type":"object","required":["format","finish_time_ms","finish_time","event_name","event_slug","result_id"],"properties":{"event_date":{"type":["string","null"],"format":"date"},"event_name":{"type":"string"},"event_slug":{"type":"string"},"finish_time":{"type":"string"},"finish_time_ms":{"type":"integer","format":"int32"},"format":{"type":"string"},"result_id":{"type":"string","format":"uuid"}}},"RaceDto":{"type":"object","required":["id","name","format","gender_scope","is_team","result_count","has_splits"],"properties":{"division":{"type":["string","null"]},"format":{"type":"string"},"gender_scope":{"type":"string"},"has_splits":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"is_team":{"type":"boolean"},"name":{"type":"string"},"race_date":{"type":["string","null"],"format":"date"},"result_count":{"type":"integer","format":"int32"},"team_size":{"type":["integer","null"],"format":"int32"}}},"RaceRefDto":{"type":"object","required":["id","name","format"],"properties":{"format":{"type":"string"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"ResultDto":{"type":"object","required":["id","event_id","race_id","display_name","status","is_provisional","has_splits"],"properties":{"age_group":{"type":["string","null"]},"age_group_count":{"type":["integer","null"],"format":"int32"},"age_group_rank":{"type":["integer","null"],"format":"int32"},"athlete_id":{"type":["string","null"],"format":"uuid"},"bib":{"type":["string","null"]},"display_name":{"type":"string"},"division":{"type":["string","null"]},"event":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/EventRefDto"}]},"event_id":{"type":"string","format":"uuid"},"finish_time":{"type":["string","null"],"description":"The same duration rendered, so a client never has to format it."},"finish_time_ms":{"type":["integer","null"],"format":"int32","description":"Canonical duration. Milliseconds, because DEKA times carry tenths and a seconds-\nresolution integer would discard the field that separates first from second place."},"gender":{"type":["string","null"]},"gender_count":{"type":["integer","null"],"format":"int32"},"gender_rank":{"type":["integer","null"],"format":"int32"},"has_splits":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"is_provisional":{"type":"boolean"},"nationality":{"type":["string","null"]},"overall_count":{"type":["integer","null"],"format":"int32"},"overall_rank":{"type":["integer","null"],"format":"int32"},"penalty_ms":{"type":["integer","null"],"format":"int32"},"race":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RaceRefDto"}]},"race_id":{"type":"string","format":"uuid"},"source_finish_time":{"type":["string","null"],"description":"Exactly what the timing provider published, kept so a parser fix is auditable."},"splits":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SplitDto"}},"status":{"type":"string"},"team":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamDto"}]}}},"SourceRefDto":{"type":"object","required":["source","external_id"],"properties":{"external_id":{"type":"string"},"source":{"type":"string"},"url":{"type":["string","null"]}}},"SplitDto":{"type":"object","required":["index","type","label","source"],"properties":{"cumulative_time":{"type":["string","null"]},"cumulative_time_ms":{"type":["integer","null"],"format":"int32"},"index":{"type":"integer","format":"int32"},"key":{"type":["string","null"]},"label":{"type":"string"},"rank":{"type":["integer","null"],"format":"int32"},"rank_count":{"type":["integer","null"],"format":"int32"},"source":{"type":"string"},"split_time":{"type":["string","null"]},"split_time_ms":{"type":["integer","null"],"format":"int32"},"type":{"type":"string"}}},"TeamDto":{"type":"object","required":["id","name","members"],"properties":{"id":{"type":"string","format":"uuid"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberDto"}},"name":{"type":"string"},"size":{"type":["integer","null"],"format":"int32"}}},"TeamMemberDto":{"type":"object","required":["name"],"properties":{"athlete_id":{"type":["string","null"],"format":"uuid"},"name":{"type":"string"}}}},"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}}},"tags":[{"name":"events","description":"DEKA events and their competitions"},{"name":"results","description":"Individual and team results, with splits"},{"name":"athletes","description":"Canonical athletes and career histories"},{"name":"leaderboards","description":"Historical global leaderboard snapshots"},{"name":"insights","description":"Paid analytics: percentile, pacing and field zone statistics"},{"name":"account","description":"Accounts, API keys, usage and plans"},{"name":"meta","description":"Formats, health and service metadata"}]}