Skip to content

Reading results

A completed session carries three things worth rendering: the measurements, the target ranges, and the annotated video.

"metrics": [
{ "key": "cadence", "value_num": 176.4, "value_json": null },
{ "key": "knee_angle_series", "value_num": null, "value_json": { "…": "…" } }
]

value_num is null when the metric is not a single number. Then value_json carries it, in one of three shapes:

  • a time series — a value per frame or per rep, for charting
  • a 2D trajectory — { kind: "trajectory", … }, an (x, y) path such as a bar path or a hip path
  • a categorical reading — a label rather than a quantity

Any one session emits only the metrics its (activity, exercise) pair defines — usually 10 to 40 of the several hundred keys in the metric dictionary. Do not assume a fixed set; iterate what you are given.

Human-readable labels, units and descriptions for every key come from the catalogue, not from the session payload. Fetch them once and cache.

"metric_targets": [
{ "key": "cadence", "min_good": 165, "max_good": 185 }
]

This is the good range for this athlete, already resolved for their gender and body size. It is deliberately separate from the measurement, because the measurement is a fact and the target is a judgement that moves with who is being measured.

Render both. A cadence of 176 means nothing on its own; 176 inside a 165–185 band means “fine, stop worrying about it”.

analyzed_url is an MP4 with the skeleton, joint angles and phase markers drawn on. Faces are blurred by default: analyzed_url shows the face blurred, and anonymized_url is your clip with the face blurred. A session created with blur_face: false has neither: its analyzed_url is not blurred and anonymized_url is empty. thumbnail_url is a still.

The raw upload is never blurred — only the analysed render is.

Every media URL in a response — video_url, analyzed_url, anonymized_url, thumbnail_url, pose3d_url, the stills inside metrics, a client’s avatar_url — is a presigned link that works for at least six days after the response that carried it, then answers 403. Store the session id, not the link, and fetch the session again when you need a fresh one. Within a UTC day the same link comes back on every read, so caches keep working; it changes when the session is re-analysed.

Check capture_findings first. A completed session whose footage the tracker could barely read still produces a full set of numbers, and they are not trustworthy — that is an advisory finding. A note only qualifies some of the numbers. See the analysis lifecycle.