List clients across the team
curl 'https://api.ai.aikynetix.app/api/clients/?q=anna' \ -H 'Authorization: Bearer aik_yourPartnerTokenHere'import requestsr = requests.get( "https://api.ai.aikynetix.app/api/clients/", headers={"Authorization": "Bearer aik_yourPartnerTokenHere"}, params={"q": "anna", "limit": 50}, timeout=30,)r.raise_for_status()page = r.json() # { results, count, next, previous }const u = new URL("https://api.ai.aikynetix.app/api/clients/");u.searchParams.set("q", "anna");u.searchParams.set("limit", "50");const r = await fetch(u, { headers: { Authorization: "Bearer aik_yourPartnerTokenHere" } });if (!r.ok) throw new Error(`HTTP ${r.status}`);const page = await r.json();Returns every Client owned by the active team, sorted alphabetically by display_name. Pass ?q=... for a free-text filter on name / email / external id. The session_count field on each Client is precomputed; fetch /api/sessions/?client=<id> for the full session list. Paginated with the standard { results, count, next, previous } envelope (limit/offset, default limit=50, max 200).
Auth: team-scoped — reachable with a partner aik_… API key as well as a user session.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Number of results to return per page.
The initial index from which to return the results.
Free-text search across display_name, email, and external_uid (case-insensitive substring match).
Responses
Section titled “Responses”object
object
Server-assigned UUID for the athlete.
Athlete’s display name as the coach refers to them. Required.
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.
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.
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.
Demographic age band derived live from age — under_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).
Declare the athlete under 18 when the date of birth doesn’t show it, or there is none (#2751). Default false. Does not change age_band, which stays from the date of birth.
Under 18 by date_of_birth, or declared so with minor_declared (#2751). India’s DPDP Act counts anyone under 18 as a child.
The parent’s or guardian’s consent in force, or null. Write an object to record one (on create or update), null to withdraw it. Without one, a minor’s analyses are always face-blurred and no public link to their data is minted or served (#2751).
object
The parent or guardian who gave consent.
How they are related to the athlete, e.g. mother, legal guardian.
How consent was given: signed_form, email, in_person or other.
signed_form- Signed formemail- Emailin_person- In personother- Other
The day the guardian consented (YYYY-MM-DD).
Anything else worth keeping, e.g. where the signed form is filed.
When it was recorded in the app.
Who recorded it (a coach’s name, or API key).
True for a minor with no guardian’s consent in force: blur is forced on every analysis and sharing answers 403 guardian_consent_required.
beginner- Beginnerintermediate- Intermediateadvanced- Advanced
Training experience: beginner / intermediate / advanced / empty string. Drives skill-level-specific green-zone overrides — a beginner and an advanced athlete are judged against different bands. Coach-set; leave blank for all-levels defaults.
beginner- Beginnerintermediate- Intermediateadvanced- Advanced
Whose words this client’s results are written in (#2867): coach (default) or amateur — Bowler Mode on bowling. Every report, PDF and new share link about the client starts from it; an activity with no amateur copy reads as coach either way.
coach- Coachamateur- Amateur
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).
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).
Optional. Leg length in centimetres (35-150). Used only by specific running analyzers when present; safe to leave null.
Free-text shoe size (e.g. 42 EU, 9 US). Coach reference only.
right- Rightleft- Leftambidextrous- Ambidextrous
right / left / ambidextrous / empty. Durable client-profile attribute; protocol reports (Tennis Serve, Running Gait) key off the dominant side. Distinct from the per-session handedness mapping.
right- Rightleft- Leftambidextrous- Ambidextrous
quarterback- Quarterbackrunning_back- Running Backwide_receiver- Wide Receivertight_end- Tight Endoffensive_line- Offensive Linedefensive_line- Defensive Linelinebacker- Linebackerdefensive_back- Defensive Back
Playing-position group for team-sport athletes: quarterback / running_back / wide_receiver / tight_end / offensive_line / defensive_line / linebacker / defensive_back / empty string. The DB Injury-Risk Battery uses it for its Defensive-Back eligibility check (warns on a non-DB athlete, never blocks). Leave blank if unknown / not a team-sport athlete.
quarterback- Quarterbackrunning_back- Running Backwide_receiver- Wide Receivertight_end- Tight Endoffensive_line- Offensive Linedefensive_line- Defensive Linelinebacker- Linebackerdefensive_back- Defensive Back
List of prior / ongoing injury entries. Each item: { id, bodyPartId, label, side?, date?, severity?, status?, resolvedDate?, note? } (mirrors the InjuryHistoryEditor item shape; date is yyyy-mm-dd or the sentinel ongoing; status is active / monitoring / resolved; resolvedDate is yyyy-mm-dd, not before date). Stored as written so a Solutions InjuryHistoryBlock renders it with no transform. Send each entry’s id back. An entry without one is matched to the stored entry with the same bodyPartId, side and date and keeps its id, so its follow-up notes and documents stay with it; when that is ambiguous and one of the candidates has notes or documents, the write is a 400 ambiguous_injury_entry. A duplicate id is a 400. Dropping an entry never deletes its notes or documents.
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.
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.
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.
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.
Number of this client’s COMPLETED sessions — the ones an analysis exists for. Read-only; computed live. The athlete pickers show this count; session_count counts every status.
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.
ISO-8601 UTC timestamp of client creation.
ISO-8601 UTC timestamp of the last mutation.
Examples
Standard pagination envelope
{ "count": 123, "next": "http://api.example.org/accounts/?offset=400&limit=100", "previous": "http://api.example.org/accounts/?offset=200&limit=100", "results": [ { "count": 2, "next": null, "previous": null, "results": [ { "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://s3.ai.aikynetix.app/aikynetix-media/teams/…/clients/…/avatar-a1b2c3d4.jpg?X-Amz-Expires=604800&X-Amz-Signature=…", "external_uid": "club-roster-id-2419", "session_count": 12, "minor_declared": false, "is_minor": false, "guardian_consent": null, "guardian_consent_required": false, "created_at": "2026-04-29T10:00:00Z", "updated_at": "2026-05-20T14:31:00Z" }, { "id": "0a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9", "display_name": "Pavel Sidorov", "email": "", "gender": "male", "height_cm": 182, "weight_kg": 78, "leg_length_cm": null, "shoe_size": "44 EU", "avatar_url": "https://s3.ai.aikynetix.app/aikynetix-media/teams/…/clients/…/avatar-a1b2c3d4.jpg?X-Amz-Expires=604800&X-Amz-Signature=…", "external_uid": "club-roster-id-2420", "session_count": 3, "minor_declared": false, "is_minor": false, "guardian_consent": null, "guardian_consent_required": false, "created_at": "2026-04-29T10:00:00Z", "updated_at": "2026-05-20T14:31:00Z" } ] } ]}object
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).
Example generated
{ "detail": "example"}