Set a password from a client link (local auth)
const url = 'http://localhost:8000/api/auth/client-invite-claim/';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"token":"Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW","password":"a-long-pass-phrase"}'};
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/auth/client-invite-claim/ \ --header 'Content-Type: application/json' \ --data '{ "token": "Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW", "password": "a-long-pass-phrase" }'Deployments that sign people in locally only (otherwise 404). With an invite token: the invited address gets a password — and an account with no team when it has none; it does not accept, the person signs in and accepts next. With a sign-in token (a coach’s Resend on an accepted grant): a new password for that account. Neither verifies the address: accepting asks for the e-mail code (403 email_unverified until then). 409 account_exists when the address already has a local password (sign in instead). Rate-limited (429). Answers 404 while client access is switched off on the environment.
Authorizations
Section titled “Authorizations”- None
Request Bodyrequired
Section titled “Request Bodyrequired”POST /api/auth/client-invite-claim/ body — the local-auth claim.
object
The password the person chooses (min 8 chars, not a common password, not all digits).
Examples
Choose a password
{ "token": "Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW", "password": "a-long-pass-phrase"}POST /api/auth/client-invite-claim/ body — the local-auth claim.
object
The password the person chooses (min 8 chars, not a common password, not all digits).
Example generated
token=example&password=examplePOST /api/auth/client-invite-claim/ body — the local-auth claim.
object
The password the person chooses (min 8 chars, not a common password, not all digits).
Responses
Section titled “Responses”object
The address to sign in with.
Examples
{ "email": "olga@example.com"}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
409 — the request conflicts with current state. detail is a stable code (e.g. reanalyze_in_flight, already_on_plan, email_in_use). Some 409s carry extra context fields alongside detail; those are documented on the specific endpoint that emits them.
Examples
409 — already has a password
{ "detail": "account_exists"}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}