Preview a client invite
const url = 'http://localhost:8000/api/client-invites/preview/';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"token":"Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url http://localhost:8000/api/client-invites/preview/ \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "token": "Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW" }'What the invite page shows before anyone signs in: the team, the coach, the athlete’s card, the relation and level, the invited address masked, and the consent version the accept must carry. Open to anyone holding the token — it rides in the body, never in a path. email_matches is null on an anonymous request and says, for a signed-in one, whether the accept would go through. Rate-limited (429). Answers 404 while client access is switched off on the environment.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”en · ru · es: the page’s language, for the coach’s fallback name. Default: the invite’s language.
Request Bodyrequired
Section titled “Request Bodyrequired”POST /api/client-invites/preview/ body. The token travels in the
body, never in a path (D4).
object
The t from the invite link’s fragment.
Examples
A token
{ "token": "Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW"}POST /api/client-invites/preview/ body. The token travels in the
body, never in a path (D4).
object
The t from the invite link’s fragment.
Example generated
token=examplePOST /api/client-invites/preview/ body. The token travels in the
body, never in a path (D4).
object
The t from the invite link’s fragment.
Responses
Section titled “Responses”What the invite page shows before anyone signs in (ClientInvitePreview).
object
The coach’s name, never an e-mail address; when they gave none, “Your coach” in ?lang, else the invite’s language.
The athlete’s card the invite opens.
athlete- Athleteguardian- Parent or guardian
view- Viewcontribute- Contribute
The invited address, masked: o***@example.com.
Whether the signed-in account’s address is the invited one; null on an anonymous request. False stops the page before consent: the accept would answer 409 invite_email_mismatch.
The consent version the accept must carry for this invite’s relation.
Examples
A guardian's invite, signed in with the invited address
{ "team_name": "North Track Academy", "invited_by_name": "Kim Larsen", "client_name": "Sofia Lebedeva", "relation": "guardian", "level": "view", "email_hint": "o***@example.com", "expires_at": "2026-11-12T09:00:00Z", "email_matches": true, "consent_version": "2026-10-29-draft"}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"}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).
Examples
404 — no such invite
{ "detail": "invite_not_found"}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).
Examples
410 — expired
The 14-day link lapsed: ask the coach to resend it.
{ "detail": "invite_expired"}410 — revoked
The coach withdrew the invite.
{ "detail": "invite_revoked"}410 — already used
The invite was accepted; sign in instead.
{ "detail": "invite_used"}object
429 — throttled: this account’s (or address’s) rate for the route is used up; try again after wait seconds, which Retry-After repeats. A route with a limit of its own answers its own code instead, documented there.
With throttled: whole seconds until the next request can pass.
Example generated
{ "detail": "example", "wait": 1}