Skip to content

Set a password from a client link (local auth)

POST
/api/auth/client-invite-claim/
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.

  • None

POST /api/auth/client-invite-claim/ body — the local-auth claim.

object
token
required
string
>= 1 characters <= 128 characters
password
required

The password the person chooses (min 8 chars, not a common password, not all digits).

string
>= 8 characters <= 128 characters

Examples

ExampleChooseAPassword

Choose a password

{
"token": "Gu7Qk2n0bVw1sXyZ-4hRt9pLmA3cE6dF8jK0oPqS5uW",
"password": "a-long-pass-phrase"
}
Media typeapplication/json
object
email
required

The address to sign in with.

string format: email

Examples

ExampleDone
{
"email": "olga@example.com"
}
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

Example generated

{
"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—NoSuchInvite

404 — no such invite

{
"detail": "invite_not_found"
}
Media typeapplication/json
object
detail
required

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.

string

Examples

Example409—AlreadyHasAPassword

409 — already has a password

{
"detail": "account_exists"
}
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

410 — expired

The 14-day link lapsed: ask the coach to resend it.

{
"detail": "invite_expired"
}
Media typeapplication/json
object
detail
required

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.

string
wait

With throttled: whole seconds until the next request can pass.

integer
nullable

Example generated

{
"detail": "example",
"wait": 1
}