Skip to content

Coach-dashboard overview

GET
/api/dashboard/overview/
curl --request GET \
--url 'http://localhost:8000/api/dashboard/overview/?range=14d' \
--header 'Authorization: Bearer <token>'

Aggregated payload for the coach Overview page. One round-trip carries the roster pulse, score pulse, activity heatmap, top movers, quota strip, and recent sessions feed.

All counts are scoped to the caller’s active team. Range must be one of 7, 14, 30, 90; default 14. Cohort comparison (delta vs prior window) is best-effort: deltas are null when the prior window is empty.

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

from
string format: date

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

group
string format: uuid

Optional ClientGroup id — narrows every roster / cohort / leaderboard / outlier figure to that group’s members. Omit for the whole-team view. A malformed id, or a group that isn’t the caller’s team, returns 404.

range
string

Preset look-back window. Accepted: 7d, 14d, 30d, 90d, 365d. Default 14d. Numeric form (7, 14, …) also accepted. Mutually exclusive with from/to.

Examples

default

14d
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/overview/.

object
range_days
required

The window the response was computed against. Echoed for the client to label its UI.

integer
range_start
required

ISO date of the window’s first day, inclusive. Useful for labelling custom-range UI (e.g. ‘Apr 1 – Apr 30’).

string format: date
range_end
required

ISO date of the window’s last day, inclusive.

string format: date
generated_at
required

Server timestamp at which the aggregation ran. Useful for ETag/cache debug.

string format: date-time
roster
required

Top-strip KPI tiles (zone B in the Overview mockup).

object
total
required

Total clients owned by the active team. Independent of session activity.

integer
active
required

Clients that had at least one session (any status) in the requested range.

integer
sessions_today
required

Sessions created since the start of the calling user’s now() day (UTC).

integer
sessions_week
required

Sessions created in the last 7 calendar days.

integer
pending_review
required

Completed sessions without a coach_review SessionMetric. Not range-bound — coaches care about the absolute backlog, not the bucket.

integer
failed_7d
required

Sessions with status=failed in the last 7 days. Quota refunded automatically per the ledger; this is a triage signal.

integer
score_pulse
required

3-up score-ring strip (zone C).

object
roster_avg
required

Average composite score (0..100) across the latest completed session of every client. Null when no client has any scored session yet.

number format: double
nullable
roster_avg_delta
required

roster_avg minus the same calculation against sessions in the prior range_days window. Null when the prior window is empty.

number format: double
nullable
at_risk
required

Clients whose latest score is below the at-risk threshold (60). Single-session sample today; a longer rolling window may replace this in Phase D-future.

integer
at_risk_delta
required

at_risk minus same metric over the prior window.

integer
streaks
required

Clients with at least 3 completed sessions in the last 7 days.

integer
streaks_delta
required

streaks minus same metric over the previous 7d slice.

integer
heatmap
required

Activity × day cells over the requested range (zone D). Sparse: empty days are omitted, the client fills gaps with zeros.

Array<object>
object
date
required

Date bucket the cell represents (UTC), YYYY-MM-DD.

string format: date
activity
required

Activity enum (running, walking, jump, …).

  • 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

Number of sessions in that activity for that day. Includes failed/pending — the heatmap is a load signal, not a success signal.

integer
activity_totals
required

Per-activity completed-session totals over the window (roster-wide, group-scoped). The client lands the Dashboards view on the activity with the most completed sessions — the one that actually has data to show — instead of a hardcoded first chip (#899). Empty when there are no completed sessions.

Array<object>
object
activity
required

Activity enum (running, walking, jump, …).

  • 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
completed
required

Completed (data-bearing) sessions for this activity in the window — the ones that produce cohort / leaderboard data. Unlike the heatmap this excludes failed/pending, so it’s the signal for which activity actually has something to show.

integer
last_completed_at
required

ISO datetime of the most-recent completed session for this activity. Tiebreak when two activities have equal completed counts (most-recent wins).

string format: date-time
nullable
movers_up
required

Up to 5 (client, activity) pairs sorted by largest positive delta (zone E left).

Array<object>
object
client_id
required

Client UUID; tap-target for navigating to /clients/:id.

string format: uuid
client_name
required

Display name (display_nameemail → empty). Empty allowed because legacy-imported clients can have neither.

string
activity
required

Activity the delta is computed on. Each (client, activity) pair is one mover row.

  • 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
delta
required

Mean score over the last 7 days minus mean score over the prior 8..30 days. Sign matches the bucket: positive in movers_up, negative in movers_down.

number format: double
movers_down
required

Up to 5 (client, activity) pairs sorted by most negative delta (zone E right).

Array<object>
object
client_id
required

Client UUID; tap-target for navigating to /clients/:id.

string format: uuid
client_name
required

Display name (display_nameemail → empty). Empty allowed because legacy-imported clients can have neither.

string
activity
required

Activity the delta is computed on. Each (client, activity) pair is one mover row.

  • 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
delta
required

Mean score over the last 7 days minus mean score over the prior 8..30 days. Sign matches the bucket: positive in movers_up, negative in movers_down.

number format: double
quota
required

Quota & subscription strip (zone F right).

object
granted
required

Sum of positive ledger entries (plan_grant:*, manual top-ups). Lifetime, not period-bound.

integer
debited
required

Absolute value of negative ledger entries — sessions consumed.

integer
remaining
required

granted - debited. Same number Me.session_quota reports.

integer
plan_name
required

Active plan display name (e.g. Pro). Null when the team has no Subscription row yet (free tier).

string
nullable
period_end
required

Subscription.current_period_end — when the next quota grant is expected. Null on free tier.

string format: date-time
nullable
days_to_renew
required

Floor of (period_end - now) in days. Null on free tier; clamped to 0 if past_due.

integer
nullable
cancel_at_period_end
required

True when the user clicked Cancel — quota stops refilling at period_end.

boolean
recent
required

5 most recent sessions, newest first (zone G).

Array<object>
object
id
required

Session UUID.

string format: uuid
seq_no
required

Stable per-team session number (#941); null on demo and pre-backfill rows.

integer
nullable
activity
required

Activity enum.

  • 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
exercise
required

Exercise preset string from EXERCISES (e.g. Treadmill, Clean). Empty when unset on legacy rows.

string
status
required

pending / processing / completed / failed.

string
created_at
required

Server-side creation timestamp.

string format: date-time
client_id
required

Client UUID, or null for legacy unattached sessions.

string format: uuid
nullable
client_name
required

client.display_nameclient.email → null.

string
nullable
score
required

Composite score SessionMetric value (0..100) when present. Null on failed/pending rows.

number format: double
nullable
recommendations
required

AI-coach insights derived from the same payload — see dashboard/recommendations.py.

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
Examples
ExampleHealthyRoster

Typical response for a small coaching team

{
"range_days": 14,
"generated_at": "2026-04-29T15:08:00Z",
"roster": {
"total": 42,
"active": 18,
"sessions_today": 11,
"sessions_week": 47,
"pending_review": 3,
"failed_7d": 0
},
"score_pulse": {
"roster_avg": 78,
"roster_avg_delta": 4,
"at_risk": 8,
"at_risk_delta": -2,
"streaks": 9,
"streaks_delta": 2
},
"heatmap": [
{
"date": "2026-04-29",
"activity": "running",
"count": 4
},
{
"date": "2026-04-29",
"activity": "jump",
"count": 2
}
],
"activity_totals": [
{
"activity": "running",
"completed": 12,
"last_completed_at": "2026-04-29T14:08:00Z"
},
{
"activity": "jump",
"completed": 3,
"last_completed_at": "2026-04-28T09:12:00Z"
}
],
"movers_up": [
{
"client_id": "0d8b…",
"client_name": "Anna Greco",
"activity": "running",
"delta": 12
}
],
"movers_down": [],
"quota": {
"granted": 200,
"debited": 13,
"remaining": 187,
"plan_name": "Pro",
"period_end": "2026-05-08T00:00:00Z",
"days_to_renew": 9,
"cancel_at_period_end": false
},
"recent": [
{
"id": "ab12…",
"seq_no": 42,
"activity": "running",
"exercise": "Treadmill",
"status": "completed",
"created_at": "2026-04-29T14:08:00Z",
"client_id": "0d8b…",
"client_name": "Anna Greco",
"score": 84
}
]
}
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"
}