Skip to content

Request a password-reset link

POST
/api/auth/password-reset/
curl --request POST \
--url http://localhost:8000/api/auth/password-reset/ \
--header 'Content-Type: application/json' \
--data '{ "email": "coach@example.com" }'

Public (unauthenticated) forgot-password request. Generates a Firebase reset link server-side, rewrites it onto the branded in-app /auth/action page, and emails it via Resend (the Firebase-Console template path is blocked by Google’s anti-abuse lock — ADR-0021 Update).

Always returns 200 with the same generic body whether or not an account exists for the email — the endpoint is deliberately enumeration-safe. Rate-limited per IP; exceeding the limit returns 429 with a Retry-After header.

  • None

Request body for the public POST /api/auth/password-reset/.

object
email
required

Email address to send the password-reset link to.

string format: email
>= 1 characters
Examples
ExampleRequestAResetLink

Request a reset link

{
"email": "coach@example.com"
}
Media typeapplication/json

Response shape for POST /api/auth/password-reset/.

Intentionally generic: the same body comes back whether or not an account exists for the email, so the endpoint can’t be used to probe which addresses are registered.

object
detail
required

Generic confirmation. Does NOT reveal whether the email is registered — always returned on a valid request.

string
Examples
ExampleGenericAcknowledgement

Same response whether or not the email is registered

{
"detail": "If an account exists for that email, a password-reset link is on its way."
}
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

429 — rate limit exceeded. Honour the Retry-After response header (seconds to wait) before retrying; it is sent on every 429.

string
Examples
Example429—TooManyResetRequestsFromThisIP

429 — Too many reset requests from this IP

{
"detail": "Request was throttled. Expected available in 30 seconds."
}