Skip to content
CrossFitAPI.com

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

MethodPathWhat it returns
GET/v1/open/{year}/workoutsA season's workouts, in order
GET/v1/games/{year}/workoutsThe Games event list
GET/v1/workouts/{id}One workout, with score type and cap
GET/v1/workouts/{id}/leaderboardEvery 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 }
}

Run these against live data →

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.

Get API access