CrossFit workouts API
CrossFit workouts API
Every competition workout as a first-class object: its score type, its time cap, its ordinal in the season, and every score anybody posted against it.
Plans from $15 a month.
A score is an integer until you decode it
Upstream, a workout result is one number. 3540044 is not a typo and it is not a rep count — it packs reps, time and a validity flag into a single integer, and the packing differs between a for-time workout, an AMRAP and a load. Nothing publishes the convention.
So the first thing every project does is reverse-engineer the encoding, and the second thing it does is get it subtly wrong for one score type and not notice for months, because the wrong answer is still a plausible number.
This API decodes it once. You get reps, time_seconds and a tiebreak where they apply, the display string the source shows, and score_raw untouched so you can verify any of it. Where we infer a time cap from the scores themselves we say so, and where the scores disagree about what the cap was we publish nothing and flag it rather than guess.
Endpoints
| Method | Path | What it returns |
|---|---|---|
| GET | /v1/open/{year}/workouts | A season's workouts, in order |
| GET | /v1/games/{year}/workouts | The Games event list |
| GET | /v1/workouts/{id} | One workout, with score type and cap |
| GET | /v1/workouts/{id}/leaderboard | Every score on that workout, ranked |
| GET | /v1/results/{id} | One athlete's card, workout by workout |
Example
Request
curl "https://api.crossfitapi.com/v1/workouts/wod_06gc8qk7qhs99bqj5vstrgnfbr/leaderboard?limit=2" \
-H "Authorization: Bearer cfapi_live_..."Response
{
"data": [
{
"rank": 1,
"score_raw": "3540044",
"score_display": "354 reps",
"reps": 354,
"time_seconds": null,
"valid": true,
"scaled": "rx",
"athlete": { "id": "ath_06gc...", "name": "..." }
}
],
"pagination": { "next_cursor": "eyJrIjoyLCJ...", "has_more": true }
}What is covered
- Every workout of every imported season, with its ordinal and score type.
- Decoded reps, times and tiebreaks, beside the untouched source value.
- Time caps, derived from the scores and marked when the scores disagree.
- Per-workout leaderboards, filterable by division and scaled.
- Validity flags, so a no-rep or an unjudged entry is visible rather than silent.
Coverage grows as each season finishes importing . A season appears there once it is imported and reconciled.
What people build with it
Workout analysis
Distribution of scores on one workout across a whole division.
Scaling research
Compare Rx, scaled and foundations fields on the same workout.
Training tools
Set a target from a real percentile instead of a guess.
Have a look at the data first
The docs and the live explorer are open, so you can see what comes back before you pay for anything.