List the team's metric thresholds
const url = 'http://localhost:8000/api/thresholds/';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url http://localhost:8000/api/thresholds/ \ --header 'Authorization: Bearer <token>'Any team member. Returns one row per metric in the requested (activity, exercise, gender) slice, each carrying either the team’s persisted override or the inherited system / MetricSpec default (with inherited=true). Used to render the threshold-configurator table.
Query params: activity (slug, optional), exercise (string, optional), gender ("" | male | female, default ""). Omitting all three returns every metric across activities.
Each row also carries norms — the Movement Norms Library reference band (ADR-0034 / #1406) for the requested slice: the exact (gender, age_band, skill_level) cohort row when all three dimensions are set and covered, else the library’s base band (scope discriminates); null when the library has no usable band for the metric. Display-only — the green-zone resolver never reads it, and a saved team row always wins (#1317).
client_group (#2518) lists a client group’s own ranges: a row the group carries comes back editable (inherited=false); otherwise the row shows what a member with no demographic slice inherits (the team’s base row, else the MetricSpec default) with inherited=true. Every row then carries client_group = that group, and observed_distribution covers the group’s members only. A group’s range wins over every cohort row for its members; a client in several groups takes, per metric, the range of the group first in ranges_priority order. 400 for an unknown / other-team group, or for one combined with a demographic filter.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Activity slug filter (optional).
"" (default, all ages) / under_18 / 18_34 / 35_49 / 50_64 / 65_69 / 70_74 / 75_79 / 80_84 / 85_plus. Demographic slice — gender is treated as more specific than age band.
Client-group UUID (#2518) — address that group’s OWN range instead of a cohort slot. Must be a group of the caller’s team and cannot be combined with gender / age_band / skill_level (both → 400, keyed on client_group).
Exercise name filter (optional).
"" (default) / male / female.
"" (default, all levels) / beginner / intermediate / advanced. Demographic slice; the resolver ranks gender > skill_level > age_band.
Responses
Section titled “Responses”object
Read shape — either a materialised team row (inherited=False,
id populated) or a synthetic catalog entry sourced from
MetricSpec (inherited=True, id=None). Plain Serializer
rather than ModelSerializer because inherited rows have no DB
backing — the container POSTs to materialise on first edit.
object
The client group this slot belongs to (#2518) — set on every row of a ?client_group= listing (materialised or inherited, so a POST knows which group it materialises into) and on a written group row; null for a cohort slot.
object
cohort- Cohortbase- Base
object
gender- genderage_band- age_bandskill_level- skill_levelheight_scaled- height_scaledsegment- segmentgroup- group
object
The slice an override row lives in — the FE’s jump target when the
coach clicks the badge to land on that cohort or group. Empty strings are
the “all” sentinel for each demographic dimension; client_group is the
group whose own range the row is (#2518), null for a cohort row.
object
object
object
Examples
One row per metric; inherited rows carry `inherited: true`
{ "items": [ { "id": "7b3d9e1a-2c4f-4a6b-8d0e-1f2a3b4c5d6e", "inherited": false, "activity": "running", "exercise": "Treadmill", "metric_key": "cadence", "client_group": null, "unit": "spm", "higher_is_better": false, "min_good": 175, "max_good": 185, "is_height_scaled": false, "norms": { "min": 170, "max": 180, "evidence_basis": "validated", "source": "Running cadence norms (Sport Science Insider)", "scope": "base" }, "overrides": [], "observed_distribution": { "bins": [], "total_sessions": 0, "axis_min": 0, "axis_max": 1, "session_window_days": 30 } }, { "id": "0a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9", "inherited": true, "activity": "running", "exercise": "Treadmill", "metric_key": "vertical_oscillation", "client_group": null, "unit": "cm", "higher_is_better": false, "min_good": 6, "max_good": 9, "is_height_scaled": false, "norms": null, "overrides": [], "observed_distribution": { "bins": [], "total_sessions": 0, "axis_min": 0, "axis_max": 1, "session_window_days": 30 } } ]}Bad client_group filter (keyed on client_group).
Validation error keyed by parameter name — client_group is malformed, names no group of the caller’s team, or rides with a demographic filter.
object
Examples
400 — client group is not this team's
{ "client_group": [ "Unknown client group for this team." ]}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Example generated
{ "detail": "example"}object
Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).
Examples
403 — partner API keys can't manage thresholds
{ "detail": "You do not have permission to perform this action."}