Skip to content

List the team's metric thresholds

GET
/api/thresholds/
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.

activity
string

Activity slug filter (optional).

age_band
string

"" (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
string

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
string

Exercise name filter (optional).

gender
string

"" (default) / male / female.

skill_level
string

"" (default, all levels) / beginner / intermediate / advanced. Demographic slice; the resolver ranks gender > skill_level > age_band.

Media typeapplication/json
object
items
required
Array<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
id
required
string
inherited
required
boolean
activity
required
string
exercise
required
string
nullable
metric_key
required
string
client_group
required

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.

string format: uuid
nullable
metric_label
required
string
unit
required
string
higher_is_better
required
boolean
nullable
min_good
required
number format: double
nullable
max_good
required
number format: double
nullable
is_height_scaled
required
boolean
default_min_good
required
number format: double
nullable
default_max_good
required
number format: double
nullable
norms
required
object
min
required
number format: double
nullable
max
required
number format: double
nullable
evidence_basis
required
string
source
required
string
scope
required
  • cohort - Cohort
  • base - Base
string
Allowed values: cohort base
overrides
required
Array<object>
object
kind
required
  • gender - gender
  • age_band - age_band
  • skill_level - skill_level
  • height_scaled - height_scaled
  • segment - segment
  • group - group
string
Allowed values: gender age_band skill_level height_scaled segment group
label
required
string
detail
required
object
key
additional properties
number format: double
nullable
slice

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
gender
required
string
age_band
required
string
skill_level
required
string
client_group
required
string format: uuid
nullable
observed_distribution
required
object
bins
required
Array<object>
object
bin_min
required
number
bin_max
required
number
count
required
integer
total_sessions
required
integer
axis_min
required
number
axis_max
required
number
session_window_days
required
integer

Examples

ExampleAThresholdSlice

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).

Media typeapplication/json

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
key
additional properties
Array<string>

Examples

Example400—ClientGroupIsNotThisTeam's

400 — client group is not this team's

{
"client_group": [
"Unknown client group for this team."
]
}
Media typeapplication/json
object
detail
required

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).

string

Example generated

{
"detail": "example"
}
Media typeapplication/json
object
detail
required

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).

string

Examples

Example403—PartnerAPIKeysCan'tManageThresholds

403 — partner API keys can't manage thresholds

{
"detail": "You do not have permission to perform this action."
}