Skip to content

Fetch a client profile by public share token

GET
/api/clients/shared/{token}/
curl --request GET \
--url http://localhost:8000/api/clients/shared/example/

Public, token-gated read of a redacted client snapshot: display name, avatar, gender, per-activity session counts, and the technique-score trend per activity. Deliberately carries no email, external id, raw session ids, or video URLs — the redaction is structural (the response schema has no fields for them). Increments the share’s view counter (atomic via F-expression). 404 for unknown or revoked tokens, 410 if the share carried an expires_at now in the past.

Auth: none — the token in the path is the credential.

  • None
token
required
string
from
string

Custom-range start (YYYY-MM-DD).

range
string

Range preset (e.g. 90d) or a custom from/to pair — windows the snapshot aggregates (tiles / score timeline / activity tabs) for the public range selector. Omit for the all-time default.

to
string

Custom-range end (YYYY-MM-DD).

Media typeapplication/json

Redacted public payload for a shared client profile.

Carries ONLY non-identifying aggregate data. The redaction is structural: there are no fields here for email, external id, raw session ids, or video URLs, so the public endpoint cannot leak them even if upstream code regressed.

object
client
required

Public athlete identity for the snapshot. ALWAYS excludes email / external id. Exposes display name / avatar / gender / skill level, and — per the #741 review (Lev), reversing Anton’s original de-scope — height / weight, gated on Anton’s privacy sign-off before the share ships (PR #755 checklist).

object
display_name
required
string
avatar_url
required
string
gender
required
string
skill_level
required
string
height_cm
required
integer
nullable
weight_kg
required
number format: double
nullable
locale
required
string
generated_at
required
string
readiness
required

0-100 composite readiness from the athlete’s recent scored sessions — the same figure shown on the coach’s profile + PDF. null when there are no completed sessions yet. A bare aggregate; carries no PII.

integer
nullable
activity_breakdown
required
Array<object>
object
activity
required
string
count
required
integer
last_session_at
required
string
nullable
trends
required
Array<object>
object
activity
required
string
metric
required
string
label
required
string
unit
required
string
target_min
required
number format: double
nullable
target_max
required
number format: double
nullable
latest
required
number format: double
nullable
points
required
Array<object>
object
created_at
required

ISO-8601 session timestamp.

string
value
required
number format: double
nullable
in_zone
required

Whether the value sits in the metric’s green zone; null when value or zone is missing.

boolean
nullable
metrics_by_activity
required

Per-activity top biomech metrics (cadence, jump height, …) as aggregate value + target zone + sparkline. Public per the #350 review decision; body-movement aggregates only — no PII.

Array<object>
object
activity
required
string
metrics
required
Array<object>

One public biomech metric card — aggregate value + target + trend. No PII: a body-movement aggregate, no name / email / id / dimensions.

object
key
required

Metric key (FE localizes via metrics.<key>).

string
label
required

English MetricSpec label (fallback).

string
unit
required
string
value
required

SI average; the client formats per unit system.

number format: double
decimals
required

Display decimals hint (avg < 10 → 2).

integer
delta
required

SI change, last session minus first.

number format: double
target_min
required
number format: double
nullable
target_max
required
number format: double
nullable
in_zone
required
boolean
nullable
higher_is_better
required

Metric polarity — the card colours its delta + sparkline by improvement, not raw direction. Null for a directionless metric.

boolean
nullable
spark
required

SI values oldest→newest (last 14) for the sparkline.

Array<number>
score_timeline
required

Overall technique score per completed session over time (all activities), oldest→newest — drives the public score chart. Same redacted point shape as trends: timestamp + value, never a session id.

Array<object>
object
created_at
required

ISO-8601 session timestamp.

string
value
required
number format: double
nullable
in_zone
required

Whether the value sits in the metric’s green zone; null when value or zone is missing.

boolean
nullable
ai_coaching
required

Latest session’s AI-coaching analysis (markdown), or null. Model-generated free text — public per the #350 full-parity share decision.

object
markdown
required
string
activity
required
string
created_at
required

ISO-8601 timestamp of the source session.

string
Examples
ExamplePublicClientSnapshot

Redacted — no email / session ids / video URLs

{
"client": {
"display_name": "Anna Petrova",
"avatar_url": "https://media.ai.aikynetix.app/teams/…/clients/…/avatar-a1b2c3d4.jpg",
"gender": "female"
},
"locale": "en",
"generated_at": "2026-06-02T09:15:00Z",
"activity_breakdown": [
{
"activity": "running",
"count": 8,
"last_session_at": "2026-05-28T17:42:00Z"
},
{
"activity": "jump",
"count": 4,
"last_session_at": "2026-05-20T11:05:00Z"
}
],
"trends": [
{
"activity": "running",
"metric": "score",
"label": "Score",
"unit": "",
"target_min": null,
"target_max": null,
"latest": 84,
"points": [
{
"created_at": "2026-05-10T17:00:00Z",
"value": 78,
"in_zone": null
},
{
"created_at": "2026-05-28T17:42:00Z",
"value": 84,
"in_zone": null
}
]
}
]
}
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—UnknownOrRevokedToken

Absent, never existed, or the coach revoked the link

{
"detail": "share_not_found"
}
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
Example410—LinkExpired

The share carried an `expires_at` now in the past

{
"detail": "share_expired"
}