Admin MFA recovery (lost device)
Auth
Admin MFA recovery (lost device)
Use a single-use recovery code to recover admin access when the operator has lost their authenticator device. Issues a fresh admin token pair.
POST
Admin MFA recovery (lost device)
Overview
When the admin’s authenticator app is lost, broken, or otherwise unavailable, the operator falls back to one of the 10 single-use recovery codes that were printed on first MFA enrollment (and replaceable via regenerate). This endpoint replaces the TOTP step of the two-step login flow with a recovery code:- The user side still authenticates by email + password — same enumeration-safe
ADMIN_INVALID_CREDENTIALSsurface as/admin/auth/login. - Instead of presenting an mfaTicket + 6-digit TOTP, the caller presents a recovery code directly.
Authentication
None. This is the recovery path — the caller IS authenticating. The endpoint is covered by the 10-requests-per-minute-per-IP burst limiter to prevent code-grinding.Path parameters
None.Query parameters
None.Request body
| Field | Type | Required | Notes | Example |
|---|---|---|---|---|
email | string | yes | Valid email, 5..254 chars. Lower-cased server-side. | admin@swappr.co.uk |
password | string | yes | 1..200 chars. The current admin password. | correct-horse-battery |
recoveryCode | string | yes | 8..64 chars. Production format is ABCD-EFGH-IJKL (14 chars), but the surface accepts a broader range for future format flexibility. | ABCD-EFGH-IJKL |
deviceFingerprint | string | no | Opaque client fingerprint, max 512 chars. Stored on the new refresh token row. | fp_9a3c… |
Example payload
Response — 200 OK
| Field | Type | Notes |
|---|---|---|
accessToken | string | Admin access token, 15-min TTL, scope admin. |
refreshToken | string | Opaque refresh token, 7-day TTL. |
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | Any field missing or out of length bounds. |
| 401 | ADMIN_INVALID_CREDENTIALS | Email + password verification failed. Enumeration-safe — same code/timing whether the email is unknown or the password is wrong. |
| 401 | MFA_INVALID_CODE | The recovery code is unknown, already consumed, or otherwise invalid. The full argon2 verify cost is still paid so timing cannot distinguish “consumed” from “wrong”. |
| 429 | RATE_LIMITED | Burst limiter tripped (10/min/IP). |
Example error — 401 MFA_INVALID_CODE
Side effects
| Effect | Notes |
|---|---|
| Recovery code consumed | The matched code is removed from the admin’s recovery-code array atomically. Other codes are unaffected. |
| Refresh token row | New row inserted with deviceFingerprint and a fresh secret. |
| Audit row | action: admin.mfa-recovery, actorType: ADMIN. |
Consuming a recovery code does not invalidate the operator’s TOTP device. If the user later finds their authenticator, they can resume using
/admin/auth/mfa-verify — only the specific code that was used is gone.See also
- Admin auth and MFA — the full login + MFA story.
- Admin login (step 1) / Verify MFA (step 2) — the normal happy-path login.
- Regenerate recovery codes — replace the 10 codes atomically (SUPER only).
curl
Postman
Seedocs/postman/swappr.postman_collection.json → Admin Auth → MFA Recovery.