Default · recovery-code entry (from “Recovery code” in frame 01; only when recoveryAvailable: true)
←Use a recovery code

Enter one of the recovery codes you saved when you turned on two-factor authentication.

Each code works once. Spaces and dashes are fine — type it the way you saved it.
Use a different method

One full-width text field (not OTP cells), default text keyboard, no auto-capitalise or spellcheck. “Verify” is disabled only while the trimmed value is empty — no format check; the server strips spaces and dashes.

Verifying · in flight (no double submit)
Use a recovery code

Enter one of the recovery codes you saved when you turned on two-factor authentication.

Error · code didn't work · 401 RECOVERY_CODE_INVALID (stays on screen, retry allowed)
Use a recovery code

That didn't work. Enter one of your saved recovery codes.

That recovery code didn't work. Check it for typos, or try another of your codes — each code works only once.

Same message for wrong, used and replaced codes (the API does not tell them apart). Nothing about time — this is not an authenticator code.

Too many attempts · 429 RATE_LIMITED (fail-closed, Retry-After countdown)
Use a recovery code
Back to sign in

Same copy and limiter as frame 02. Wait = 429 Retry-After (seconds), shown as a live m:ss countdown; “Try again” disabled until it hits zero. Header missing/invalid → “Wait a few minutes, then try again.”, button enabled. Code kept, not marked red.

Sign-in expired · 401 NOT_ACTIVE (challenge dead — restart; no claim about the code)
Use a recovery code
Error · couldn't check the code (network / 5xx / unrecognised)
Use a recovery code

Does not claim the code is still unused — if the reply was lost after the server accepted it, the code is spent.

Frame 05 · Recovery code · /login/mfa — 375px (Android TWA) · All frames

Review · mfa-stepup-mobile approve or reject each flow ↓
mfa-stepup-mobileapproved · izzywdev
confirm-contact-phoneapproved · izzywdev
security-status-mobileapproved · izzywdev