Skip to content

Update a client (partial)

PATCH
/api/clients/{id}/
curl --request PATCH \
--url http://localhost:8000/api/clients/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/ \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "weight_kg": 60, "avatar_url": "https://media.ai.aikynetix.app/teams/…/clients/…/avatar-a1b2c3d4.jpg" }'

Partial update — send only the fields you want to change. Same body-aware-adjustment semantics as PUT (changes apply to subsequent sessions only).

id
required
string format: uuid
object
display_name

Athlete’s display name as the coach refers to them. Required.

string
>= 1 characters <= 200 characters
email
Any of:
string format: email
<= 254 characters
gender

male / female / nonbinary / empty string — case and surrounding whitespace are normalised, anything else is a 400. Drives gender-specific green-zone overrides on running cadence, stride length, jump power, and other normative metrics. Leave blank if unknown — you’ll get the all-genders defaults.

string
<= 16 characters
date_of_birth

ISO date (YYYY-MM-DD). Required on write; reads back null on athletes migrated before the requirement. Drives age-band-aware green zones — a masters runner and a junior are judged against age-appropriate bands. Stored as the date, not the age, so it never goes stale.

string format: date
skill_level
One of:
  • beginner - Beginner
  • intermediate - Intermediate
  • advanced - Advanced
string
Allowed values: beginner intermediate advanced
height_cm

Standing height in centimetres (55-260). Required on write; reads back null on athletes migrated before the requirement. Drives proportional scaling of stride length, vertical oscillation, step width, and trunk sway green zones (legacy rows without it fall back to a 170 cm reference).

integer
<= 32767
weight_kg

Body weight in kilograms (20-400). Required on write; reads back null on athletes migrated before the requirement — drives force / power / impulse metrics on jump and agility activities (legacy rows without it fall back to 75 kg, which can introduce 20-30% error on those readings).

number format: double
leg_length_cm

Optional. Leg length in centimetres (35-150). Used only by specific running analyzers when present; safe to leave null.

number format: double
nullable
shoe_size

Free-text shoe size (e.g. 42 EU, 9 US). Coach reference only.

string
<= 16 characters
avatar_url
Any of:
string format: uri
<= 200 characters
dominant_hand
One of:
  • right - Right
  • left - Left
  • ambidextrous - Ambidextrous
string
Allowed values: right left ambidextrous
position
One of:
  • quarterback - Quarterback
  • running_back - Running Back
  • wide_receiver - Wide Receiver
  • tight_end - Tight End
  • offensive_line - Offensive Line
  • defensive_line - Defensive Line
  • linebacker - Linebacker
  • defensive_back - Defensive Back
string
Allowed values: quarterback running_back wide_receiver tight_end offensive_line defensive_line linebacker defensive_back
injury_history

List of prior / ongoing injury entries. Each item: { id, bodyPartId, label, side?, date?, severity?, note? } (mirrors the InjuryHistoryEditor item shape; date is yyyy-mm-dd or the sentinel ongoing). Stored verbatim so a Solutions InjuryHistoryBlock renders it with no transform.

workstation_setup

Reusable Workspace Wellness workstation setup — { posture, measurements_cm: { desktop_height, seat_top_height?, seat_pan_depth?, back_rest_height?, eye_level_height, screen_top_height } } (mirrors WorkstationSetupSerializer; seat fields required only when posture is seated). The ergonomics survey step pre-fills from this so a returning subject doesn’t re-measure their desk; each session snapshots its own point-in-time copy. Empty object {} means unset. See #303 / #530.

notes

Coach’s free-text notes on the athlete — the general-purpose field that replaced the narrow sport_type / nature_of_work questions (#926). Bounded to 2000 chars.

string
<= 2000 characters
Examples
ExamplePatchACoupleOfFields

PATCH sends only what changes

{
"weight_kg": 60,
"avatar_url": "https://media.ai.aikynetix.app/teams/…/clients/…/avatar-a1b2c3d4.jpg"
}
Media typeapplication/json
object
id
required

Server-assigned UUID for the athlete.

string format: uuid
display_name
required

Athlete’s display name as the coach refers to them. Required.

string
<= 200 characters
email
Any of:
string format: email
<= 254 characters
gender

male / female / nonbinary / empty string — case and surrounding whitespace are normalised, anything else is a 400. Drives gender-specific green-zone overrides on running cadence, stride length, jump power, and other normative metrics. Leave blank if unknown — you’ll get the all-genders defaults.

string
<= 16 characters
date_of_birth
required

ISO date (YYYY-MM-DD). Required on write; reads back null on athletes migrated before the requirement. Drives age-band-aware green zones — a masters runner and a junior are judged against age-appropriate bands. Stored as the date, not the age, so it never goes stale.

string format: date
nullable
age
required

Whole-years chronological age, computed live from date_of_birth (never stored). null when no DOB is set. Drives age-band-aware metric green zones.

integer
nullable
age_band
required

Demographic age band derived live from ageunder_18 / 18_34 / 35_49 / 50_64, then five-year bands above 65 (65_69 / 70_74 / 75_79 / 80_84 / 85_plus), or "" when no DOB is set. The same slice the green-zone resolver and the threshold configurator use; band cutoffs are server-owned so clients never re-derive them (#1406).

string
skill_level
One of:
  • beginner - Beginner
  • intermediate - Intermediate
  • advanced - Advanced
string
Allowed values: beginner intermediate advanced
height_cm
required

Standing height in centimetres (55-260). Required on write; reads back null on athletes migrated before the requirement. Drives proportional scaling of stride length, vertical oscillation, step width, and trunk sway green zones (legacy rows without it fall back to a 170 cm reference).

integer
nullable <= 32767
weight_kg
required

Body weight in kilograms (20-400). Required on write; reads back null on athletes migrated before the requirement — drives force / power / impulse metrics on jump and agility activities (legacy rows without it fall back to 75 kg, which can introduce 20-30% error on those readings).

number format: double
nullable
leg_length_cm

Optional. Leg length in centimetres (35-150). Used only by specific running analyzers when present; safe to leave null.

number format: double
nullable
shoe_size

Free-text shoe size (e.g. 42 EU, 9 US). Coach reference only.

string
<= 16 characters
avatar_url
Any of:
string format: uri
<= 200 characters
dominant_hand
One of:
  • right - Right
  • left - Left
  • ambidextrous - Ambidextrous
string
Allowed values: right left ambidextrous
position
One of:
  • quarterback - Quarterback
  • running_back - Running Back
  • wide_receiver - Wide Receiver
  • tight_end - Tight End
  • offensive_line - Offensive Line
  • defensive_line - Defensive Line
  • linebacker - Linebacker
  • defensive_back - Defensive Back
string
Allowed values: quarterback running_back wide_receiver tight_end offensive_line defensive_line linebacker defensive_back
injury_history

List of prior / ongoing injury entries. Each item: { id, bodyPartId, label, side?, date?, severity?, note? } (mirrors the InjuryHistoryEditor item shape; date is yyyy-mm-dd or the sentinel ongoing). Stored verbatim so a Solutions InjuryHistoryBlock renders it with no transform.

workstation_setup

Reusable Workspace Wellness workstation setup — { posture, measurements_cm: { desktop_height, seat_top_height?, seat_pan_depth?, back_rest_height?, eye_level_height, screen_top_height } } (mirrors WorkstationSetupSerializer; seat fields required only when posture is seated). The ergonomics survey step pre-fills from this so a returning subject doesn’t re-measure their desk; each session snapshots its own point-in-time copy. Empty object {} means unset. See #303 / #530.

notes

Coach’s free-text notes on the athlete — the general-purpose field that replaced the narrow sport_type / nature_of_work questions (#926). Bounded to 2000 chars.

string
<= 2000 characters
external_uid
required

Your own stable id for this athlete in your external system (athlete-management software, club ID, etc.). We never interpret this; useful for cross-system joins. Read-only here — set at create time only.

string
session_count
required

Number of sessions tied to this client. Read-only; computed live. The web’s delete-confirm dialog uses this to spell out how much history a delete will wipe.

integer
group_ids
required

UUIDs of the ClientGroups this athlete belongs to (#545) — many-to-many, so an athlete can be in several. Drives the group chips + filter on the Clients page; mutate via the /api/client-groups/<id>/members/ endpoints, never here.

Array<string>
created_at
required

ISO-8601 UTC timestamp of client creation.

string format: date-time
updated_at
required

ISO-8601 UTC timestamp of the last mutation.

string format: date-time
Examples
ExampleAClient

A client

{
"id": "f6d52e64-3aa3-4a26-bac2-0fc9d718448d",
"display_name": "Anna Petrova",
"email": "anna@example.com",
"gender": "female",
"height_cm": 168,
"weight_kg": 58,
"leg_length_cm": null,
"shoe_size": "38 EU",
"avatar_url": "https://media.ai.aikynetix.app/teams/…/clients/…/avatar-a1b2c3d4.jpg",
"external_uid": "club-roster-id-2419",
"session_count": 12,
"created_at": "2026-04-29T10:00:00Z",
"updated_at": "2026-05-20T14:31:00Z"
}
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—NoSuchClientOnThisTeam

Absent, or owned by another team (collapsed to 404)

{
"detail": "No Client matches the given query."
}