# roxapi

> An independent REST API for HYROX race results: seasons, events, the race calendar, full finisher lists, all eight runs and eight stations of every result, athlete search and history, percentiles, pacing and field statistics. JSON over HTTPS with Bearer auth. Not affiliated with or endorsed by HYROX.

Useful if you are building a training app, a race time predictor, a coaching tool or a club leaderboard and need HYROX results as data.

## Getting started

1. Create an account at https://roxapi.dev/signup and pick a plan (billed monthly through Stripe).
2. Create an API key in the dashboard. It is shown once.
3. Send it on every request: `Authorization: Bearer <key>`.

```bash
curl -H "Authorization: Bearer $KEY" "https://roxapi.dev/api/v1/athletes/search?last=McIntyre&first=Hunter"
```

Every response, including errors, uses one envelope: `{ "data": ..., "meta": ..., "errors": null | [...] }`. Times are integers in milliseconds (`total_time_ms`). Rate limits are per account and reported in `X-RateLimit-*` headers; a 429 means slow down, a 402 means the endpoint needs a higher plan.

## Reference

- [OpenAPI 3.1 spec](https://roxapi.dev/api/v1/openapi.yaml): the complete, machine-readable contract. Prefer it over this summary.
- [API reference](https://roxapi.dev/docs): the same spec, rendered for people.

## Endpoints

- `GET /api/v1/seasons`: HYROX seasons; their slugs filter other endpoints.
- `GET /api/v1/races`: the upcoming race calendar, one row per race, months ahead.
- `GET /api/v1/events`: every event, filterable by `season`, `country` (ISO alpha-2), `from`/`to` dates; `upcoming=true` for future races.
- `GET /api/v1/events/{slug}` and `/api/v1/events/{slug}/divisions`: one event and its divisions (Open, Pro, Doubles, Relay, by sex and day).
- `GET /api/v1/divisions/{id}/results`: the finisher list of a division, cursor-paginated (`limit` up to 100, follow `meta.cursor`), filterable by `sex`, `age_class`, `nation`, `name`.
- `GET /api/v1/athletes/search?last=&first=`: find an athlete; one row per race. Returns a race `id` and a `person_ref`.
- `GET /api/v1/athletes/{id}`: one race result in detail.
- `GET /api/v1/athletes/{id}/results`: an athlete's race history (pass the `person_ref`).
- `GET /api/v1/athletes/{id}/splits`: every run, station and Roxzone split of a result.
- `GET /api/v1/stats/divisions/{id}`: finish-time distributions by division, sex and age group.
- `GET /api/v1/stats/divisions/{id}/splits`: per-station field medians for an event.
- `GET /api/v1/percentile?total_time_ms=&division=&sex=&age_group=`: rank any finish time against every comparable athlete, not just one race.
- `GET /api/v1/athletes/{id}/pacing`: run fade, lap consistency, Roxzone share, where the time went.
- `GET /api/v1/athletes/{id}/partners`: Doubles and Relay team-mates.
- `GET /api/v1/simulator/benchmarks` and `/api/v1/simulator/division-benchmarks`: target times per station for race simulators.
- `GET /api/user`: the current account, plan and limits.
- `GET /api/v1/health`: public, no key needed.

## Identifiers

- An event has a string `slug` and an integer `id`; division results and stats take the integer `id`.
- Athlete-search results carry opaque ids. Pass them back unchanged; do not parse or construct them.
- Ids are stable: store them.

## Plans

- Starter (€7.99/month): 30 requests/minute; per 24 h: 500 athlete IDs, 20 division IDs, 15 event slugs, 10 athlete profile slugs
- Pro (€19.99/month): 100 requests/minute; per 24 h: 1,500 athlete IDs, 50 division IDs, 40 event slugs, 25 athlete profile slugs; includes percentile, pacing and team-mates
- Scale (€49.99/month): 1,000 requests/minute; per 24 h: 5,000 athlete IDs, 150 division IDs, 100 event slugs, 75 athlete profile slugs; includes percentile, pacing and team-mates, per-station field distributions

Limits apply per account, across all of its keys. Change plan or cancel any time from the dashboard.
