Sign-in and registration
POST /v1/auth/login and POST /v1/auth/register — start parameters, flow token and available verification methods.
Sign-in and registration share one shape: submit an identifier and a device id, receive a flow token (JWE), then complete the verification challenges one by one. The only difference is where the methods come from — sign-in compares against existing credentials, registration stages the new ones inside the flow token.
Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /v1/auth/login | Start sign-in |
POST | /v1/auth/register | Start registration |
Both require a Cloudflare Turnstile token. It is the only thing standing between this endpoint and bulk scripting, so a missing or failed token is rejected outright.
Request body
| Parameter | Type | Required | Notes |
|---|---|---|---|
id | string | ✅ | Username or email, 3–255 chars; trimmed and lowercased server-side |
did | string | ✅ | Device id, 8–256 chars; first-party sessions are accounted per device |
turnstile | string | ✅ | Turnstile token |
{
"id": "[email protected]",
"did": "device-8f3a1c2b",
"turnstile": "0.xxxxx"
}Response
{
"success": true,
"flow_token": "eyJhbGciOi...",
"available_methods": [
{ "type": "email", "masked": "a***@example.com", "remaining": 1 },
{ "type": "passkey", "remaining": 1 }
]
}| Field | Notes |
|---|---|
flow_token | The flow token (JWE). Every subsequent verification request sends it as Authorization: Bearer, and the server rotates it each time |
available_methods[].type | email / password / passkey / authenticator / recovery_code |
available_methods[].masked | Masked contact value; present for email only |
available_methods[].remaining | Remaining attempts for that method |
available_methods may be empty on registration
A brand-new account has no verified credential yet, so this array can be empty in the registration response. An empty array means "no method available yet", not "registration failed".
What happens next
- Use
flow_tokenwith the matching endpoint in Verification challenges; - every successful step returns a new
flow_token; continue with the new one, the old one stops working; - once all required steps are done, call
POST /tokenin Tokens with the lastflow_tokento obtain an access token and a refresh token.
Silent failure
During sign-in, if the requested email does not match the methods recorded in the flow token, the server returns success without sending anything. This is deliberate: an error would tell the caller "this account has no such email", leaking the account's structure.
Related
- Each verification step: Verification challenges
- Exchanging the flow token: Tokens
- Signing in with a third-party account: Third-party callback