Skip to content

Per-client metric trend

GET
/api/dashboard/client/{id}/trend/
curl --request GET \
--url 'http://localhost:8000/api/dashboard/client/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/trend/?activity=example' \
--header 'Authorization: Bearer <token>'

Per-session timeline of one metric for one client over an (activity, range) window. Each point in series carries the metric value at that session, the composite score, and the spec target band (min_good/max_good). activity_breakdown lets the frontend render the activity-tabs strip without a second round-trip.

Unknown activity404; unknown metric400; client not on the active team → 404.

Source-of-truth doc: project_context/product/COACH_DASHBOARD_PLAN.md §6 / §9.1.

id
required
string format: uuid

Client UUID. Must belong to the active team — otherwise 404.

activity
required
string

One of the closed Activity enum values.

from
string format: date

Custom-range start (ISO YYYY-MM-DD, inclusive). Takes precedence over range.

metric
string

MetricSpec key. Defaults to the first headline metric for the activity.

range
string

Preset look-back — 7d / 14d / 30d / 90d / 365d. Mutually exclusive with from/to.

to
string format: date

Custom-range end (ISO YYYY-MM-DD, inclusive). Defaults to today.

tz
string

Viewer’s IANA timezone (e.g. America/Chicago). The look-back window AND the daily/weekly buckets are computed in it, so a session lands on the coach’s local day, not the server’s UTC day. Omit to fall back to UTC (legacy / partner-key callers).

Media typeapplication/json

Shape of GET /api/dashboard/client/{id}/trend/.

object
client_id
required
string format: uuid
activity
required
  • running - Running
  • walking - Walking
  • jump - Vertical Jump
  • weightlifting - Weightlifting
  • mobility - Mobility Assessment
  • workspace_wellness - Workspace Wellness
  • agility - Agility
  • fencing - Fencing
  • cycling - Cycling
  • tennis - Tennis
  • padel - Padel Tennis
  • bowling - Bowling
  • baseball - Baseball
  • football - Football
  • badminton - Badminton
  • cricket - Cricket
  • basketball - Basketball
  • scuba_diving - Scuba Diving
  • ice_hockey - Ice Hockey
  • american_football - American Football
  • fri - Falls Risk Indicator
string
Allowed values: running walking jump weightlifting mobility workspace_wellness agility fencing cycling tennis padel bowling baseball football badminton cricket basketball scuba_diving ice_hockey american_football fri
range_days
required
integer
range_start
required

ISO date of the window’s first day (inclusive).

string format: date
range_end
required

ISO date of the window’s last day (inclusive).

string format: date
metric
required
string
available_metrics
required
Array<object>
object
key
required
string
label
required
string
unit
required

One of the canonical Unit literal strings (see domain/metrics/base.py).

string
higher_is_better
required
boolean
nullable
min_good
required
number format: double
nullable
max_good
required
number format: double
nullable
beta
required

Metric has not cleared clinical / force-plate validation; the UI shows a ‘beta’ precision caveat.

boolean
headline_metrics
required
Array<string>
activity_breakdown
required
Array<object>
object
activity
required
  • running - Running
  • walking - Walking
  • jump - Vertical Jump
  • weightlifting - Weightlifting
  • mobility - Mobility Assessment
  • workspace_wellness - Workspace Wellness
  • agility - Agility
  • fencing - Fencing
  • cycling - Cycling
  • tennis - Tennis
  • padel - Padel Tennis
  • bowling - Bowling
  • baseball - Baseball
  • football - Football
  • badminton - Badminton
  • cricket - Cricket
  • basketball - Basketball
  • scuba_diving - Scuba Diving
  • ice_hockey - Ice Hockey
  • american_football - American Football
  • fri - Falls Risk Indicator
string
Allowed values: running walking jump weightlifting mobility workspace_wellness agility fencing cycling tennis padel bowling baseball football badminton cricket basketball scuba_diving ice_hockey american_football fri
count
required
integer
last_session_at
required
string format: date-time
nullable
series
required
Array<object>
object
session_id
required
string format: uuid
created_at
required
string format: date-time
value
required

Metric value at this session. Null when the analyzer didn’t emit it (e.g. front-only metric on a side-view session).

number format: double
nullable
score
required

Composite score for the session, when present.

number format: double
nullable
target_min
required

Lower green bound, resolved for THIS athlete (domain.target_bands, #1317) — the same band the session card, the PDF and the Solutions report show, not the MetricSpec population default. Null when no curated zone applies.

number format: double
nullable
target_max
required
number format: double
nullable
in_zone
required

True / false / null. Null when value or zone is missing.

boolean
nullable
delta_vs_prev
required

This value minus the previous recorded (non-null) value in the window — null for the first reading or a null value. The per-session Δ. #609 Phase 3 (shared with #424).

number format: double
nullable
is_personal_best
required

True when this value equals the window’s best (by higher_is_better) — drives the personal-best marker. #609 Phase 3.

boolean
baseline
required

First recorded value in the window — the progress reference. Null when no session has a value. #609 Phase 3.

number format: double
nullable
personal_best
required

Best value in the window, by the metric’s higher_is_better. Null when no value, or the metric has no good/bad direction. #609 Phase 3.

number format: double
nullable
generated_at
required
string format: date-time
recommendations
required
Array<object>

One AI-coach insight attached to a dashboard response.

Server returns the i18n keys + interpolation vars; the frontend renders the localised copy. This keeps server-side from owning user-facing English/Russian strings.

object
kind
required

Semantic category — drives icon + i18n key on the client.

string
severity
required

Drives the tone-bar colour: info → sleep, warning → form, critical → recovery-low.

  • info - info
  • warning - warning
  • critical - critical
string
Allowed values: info warning critical
title_key
required

I18n key for the headline. Frontend interpolates with title_vars.

string
title_vars
required

Vars for title_key interpolation.

object
key
additional properties
body_key
required
string
nullable
body_vars
required
object
key
additional properties
cta_label_key
required
string
nullable
cta_href
required
string
nullable
Example
{
"activity": "running",
"activity_breakdown": [
{
"activity": "running"
}
],
"recommendations": [
{
"severity": "info"
}
]
}
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
Examplegenerated
{
"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
Examplegenerated
{
"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
Example404—NoActiveTeam

404 — No active team

{
"detail": "No active team — finish onboarding first."
}