Platform
Errors and recovery
Error response shapes, the codes you can act on, and SDK errors.
Response format#
Errors are JSON with a message and, where there is something to act on, a stable code: { "error": "…", "code": "…" }. Match on the code and status, not on the message: messages are for people and may change.
Codes to handle#
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | invalid_credentials | Wrong password or unknown account (deliberately the same) | Ask the user to check and try again |
| 400 | invalid_token | Reset link expired, used or invalid | Offer a new link |
| 403 | bot_check_failed | Cloudflare check failed or missing | Let the user retry the check |
| 503 | bot_check_unavailable | Turnstile half-configured (operators) | Set both Turnstile keys |
| 401 | account_blocked | The account is blocked or deprovisioned | Sign the user out |
| 403 | not_a_member | Switching to an organization the user is not in | Refresh the organization list |
| 400/401 | invalid_grant / invalid_client | A sign-in code was reused, expired, or redeemed with the wrong key or redirect URI | Start sign-in again; check the callback URL |
| 403 | — | A method is turned off for the environment (sign-up, social, magic codes, passkeys) | Turn it on, or hide the option |
| 429 | — | Rate limited | Wait before retrying |
SDK errors#
AuthClientmethods throw anErrorwithstatusCodeandcode(theAuthErrortype). The error class itself is not exported, so check the fields.verifyWebhookthrowsWebhookVerificationError.verifySessionTokennever throws: it returnsvalid,legacyorinvalidwith a reason.- The callback route redirects back to your app with
?error=when a code can't be redeemed, instead of showing a server error. - With no
AUTH_API_URLin production the SDK throws on the first request rather than use the development API; with no client ID the middleware answers protected routes with500and says why.
Recovering#
- Session errors: send the user through sign-in again; the SDK clears nothing you need to clean up yourself.
- Refresh failures keep the current token until it expires, then the middleware sends the user to sign-in.
- Webhook failures are retried for a day and can be replayed after that.