Verify MFA (step 2 of 2)
Auth
Verify MFA (step 2 of 2)
Exchange the MFA ticket from /admin/auth/login plus a 6-digit TOTP code for an admin access + refresh token pair.
POST
Verify MFA (step 2 of 2)
Overview
Second and final step of admin login. Present themfaTicket returned by POST /admin/auth/login together with the current 6-digit TOTP code from the operator’s authenticator app. On success the server issues:
- an access token — RS256 JWT,
scope: 'admin', 15-minute TTL. Required asBeareron every other admin endpoint. - a refresh token — opaque, 7-day TTL, stored hashed in the
admin_refresh_tokenscollection.
No authentication header. The
mfaTicket is the credential. Same 10/min/IP burst limiter as /admin/auth/login.Authentication
None. ThemfaTicket authenticates the request.
Path parameters
None.Query parameters
None.Request body
| Field | Type | Required | Notes | Example |
|---|---|---|---|---|
mfaTicket | string | yes | The ticket from step 1. 1..4096 chars. Expires 5 minutes after issue. | eyJhbGciOiJI… |
totp | string | yes | Exactly 6 digits (/^\d{6}$/). The current code from the authenticator app (30-second window). | 492013 |
deviceFingerprint | string | no | Opaque client fingerprint, max 512 chars. Stored on the refresh-token row for later session attribution. | fp_9a3c… |
Example payload
Response — 200 OK
| Field | Type | Notes | Example |
|---|---|---|---|
accessToken | string | RS256 JWT, scope: 'admin', 15-minute TTL. Send as Authorization: Bearer <accessToken>. | eyJhbGciOiJSUzI1NiI… |
refreshToken | string | Opaque 7-day refresh token. Store securely; rotate via /admin/auth/refresh. | rt_a1b2c3… |
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | mfaTicket missing, totp not exactly 6 digits. |
| 401 | INVALID_MFA_TICKET | Ticket malformed, expired (> 5 min), or the admin was deleted / un-enrolled between login and verify. Re-do step 1. |
| 401 | MFA_INVALID_CODE | TOTP code did not validate against the admin’s secret (wrong code or clock skew). |
Example error — 401 MFA_INVALID_CODE
See also
- Admin login (step 1) — obtain the
mfaTicket. - Admin refresh — rotate the token pair.
- Admin auth and MFA — TOTP enrollment + recovery.
curl
Postman
Seedocs/postman/swappr.postman_collection.json → Admin Auth → MFA verify.