Skip to content

OpenBody in five minutes

OpenBody is an open, portable JSON format for health & fitness data — all of it, not one gym’s worth: strength and calisthenics, running, cycling, swimming and hiking, climbing, team and combat sports, mobility and breathwork. This page is the 20% you’ll use every day, as seven real records. Every example below validates against the published JSON Schema — copy them and go.

Two kinds of data, one format:

  • Observation — measurements: heart rate, sleep, steps, GPS, body composition.
  • Structured training — sessions, exercises, sets, reps, load, intervals, continuous efforts, and the planned-versus-performed relationship. One scoring model (reps | time | distance | continuous | energy) spans a barbell set, a plank hold, a swim interval, and a marathon.

1. A measurement

A heart-rate reading. Every measurement is type + value + unit + a time window (instantaneous when startTime equals endTime), with optional provenance saying where it came from.

{
"id": "obs-9f2a1c",
"recordType": "Measurement",
"subject": "subj-001",
"type": "heart_rate",
"quantity": 72,
"unit": "/min",
"startTime": "2026-06-23T14:02:00Z",
"endTime": "2026-06-23T14:02:00Z",
"provenance": { "method": "sensor", "device": { "manufacturer": "apple", "model": "Watch Ultra 2" } }
}

Time series (a whole HR stream, a GPS route) use the same record with a sampleArray instead of quantity — see the data model.

2. A logged set

One set of squats: what was prescribed, and what actually happened — on the same record. exerciseRef is a canonical id from the exercise registry, so every app that speaks OpenBody agrees on which movement this is.

{
"id": "wu-squat-1",
"recordType": "WorkUnit",
"subject": "subj-001",
"exerciseRef": "squat.barbell.high-bar",
"scoring": "reps",
"setRole": "working",
"prescription": { "reps": 5, "load": { "value": 100, "unit": "kg", "basis": "marked_weight" } },
"performance": {
"reps": 5,
"load": { "value": 100, "unit": "kg", "basis": "marked_weight" },
"effortLoad": [{ "kind": "internal", "method": "RPE", "value": 8 }]
}
}

3. A run

Not everything is sets and reps. A continuous effort — a run, a ride, a swim, a hike — is a WorkUnit with scoring: "continuous", carrying whichever of distance/time/energy you have. The measuredBy links point at the Pillar A telemetry recorded during it (the HR stream, the GPS route), so the training record and the sensor data stay connected without duplicating either:

{
"id": "sess-run-12",
"recordType": "Session",
"subject": "subj-001",
"intent": "train",
"disciplines": ["running"],
"workUnits": [{
"id": "wu-run",
"recordType": "WorkUnit",
"scoring": "continuous",
"performance": {
"distance": { "absolute": { "value": 10000, "unit": "m" } },
"time": { "absolute": { "value": 2520, "unit": "s" } }
},
"links": [
{ "type": "measuredBy", "ref": "obs-route-77" },
{ "type": "measuredBy", "ref": "obs-hr-stream-3" }
]
}]
}

The same shape with disciplines: ["cycling"] and power intensity targets is an interval ride; with ["swimming"], a swim set (SWOLF and stroke data ride along as measurements and open tokens). See the coverage corpus for worked records across cycling intervals, zone runs, swim send-offs, freediving, hiking-style accumulation days, and more.

4. A strength session

A gym workout is a Session containing Exercises, each containing its sets (WorkUnits). This is the shape a typical strength-app export converts into:

{
"id": "sess-push-mon",
"recordType": "Session",
"subject": "subj-001",
"intent": "train",
"disciplines": ["strength"],
"name": "Push day",
"exercises": [
{
"id": "ex-bench",
"recordType": "Exercise",
"exerciseRef": "bench-press.barbell.flat",
"workUnits": [
{ "id": "wu-bench-1", "recordType": "WorkUnit", "scoring": "reps", "setRole": "working",
"performance": { "reps": 8, "load": { "value": 80, "unit": "kg", "basis": "marked_weight" } } },
{ "id": "wu-bench-2", "recordType": "WorkUnit", "scoring": "reps", "setRole": "working",
"performance": { "reps": 6, "load": { "value": 80, "unit": "kg", "basis": "marked_weight" } } }
]
},
{
"id": "ex-pushup",
"recordType": "Exercise",
"exerciseRef": "push-up",
"workUnits": [
{ "id": "wu-pushup-1", "recordType": "WorkUnit", "scoring": "reps",
"performance": { "reps": 20 } }
]
}
]
}

5. A superset

Grouping structure is a Block. grouping: "superset" says the children alternate; the same mechanism covers circuits, giant sets, and drop sets. This planned superset also shows richer prescription: sets: 3 shorthand, %1RM relative load, RIR effort, and rest.

{
"id": "blk-superset-1",
"recordType": "Block",
"subject": "subj-001",
"grouping": "superset",
"children": [
{
"id": "ex-001", "recordType": "Exercise", "exerciseRef": "bench-press.barbell.flat",
"workUnits": [{
"id": "wu-001", "recordType": "WorkUnit", "scoring": "reps", "setRole": "working",
"prescription": {
"sets": 3, "reps": 5,
"load": { "value": { "relativeToThreshold": { "percent": 80, "of": "1RM" } }, "basis": "marked_weight" },
"rest": { "absolute": { "value": 120, "unit": "s" } }
}
}]
},
{
"id": "ex-002", "recordType": "Exercise", "exerciseRef": "row.barbell.bent-over",
"workUnits": [{
"id": "wu-002", "recordType": "WorkUnit", "scoring": "reps",
"prescription": { "sets": 3, "reps": 8, "effortLoad": [{ "kind": "internal", "method": "RIR", "value": 2 }] }
}]
}
]
}

6. Planned vs performed

A plan and its execution can also live in separate records, linked by a typed performedFrom link — so a coach’s program and an athlete’s log stay distinct but connected. The planned sets: 5 shorthand expands to five work units; the performed side enumerates one record per actual set (here, the first).

{
"id": "plan-squat-mon",
"recordType": "WorkUnit",
"subject": "subj-001",
"exerciseRef": "squat.barbell.high-bar",
"scoring": "reps",
"prescription": { "sets": 5, "reps": 5, "load": { "value": 100, "unit": "kg", "basis": "marked_weight" } }
}
{
"id": "perf-squat-1",
"recordType": "WorkUnit",
"subject": "subj-001",
"exerciseRef": "squat.barbell.high-bar",
"scoring": "reps",
"links": [{ "type": "performedFrom", "ref": "plan-squat-mon" }],
"performance": {
"reps": 5,
"load": { "value": 100, "unit": "kg", "basis": "marked_weight" },
"effortLoad": [{ "kind": "internal", "method": "RPE", "value": 8 }]
}
}

7. A sport result

Skill and sport outcomes are first-class, not shoehorned into reps. A bouldering problem: sent once in 3 attempts, grade carried as an open token. The same outcome mechanism covers a race placement, a match score, a judged gymnastics routine, or a Highland-games throw:

{
"id": "wu-boulder-v5",
"recordType": "WorkUnit",
"subject": "subj-001",
"exerciseRef": { "opaque": "boulder problem" },
"scoring": "reps",
"performance": {
"reps": 3,
"modifiers": [{ "type": "grade", "value": "V5" }],
"outcome": {
"kind": "success",
"value": true,
"attempts": { "made": 1, "attempted": 3 }
}
}
}

Where to go deeper