Prerequisites
Before this page: create and initialize a Dynamic client (see Creating a Dynamic client, Initializing the Dynamic client), and have a signed-in user (see Email & SMS OTP sign-in or Social OAuth).What you’ll build
- Enroll an authenticator app (TOTP) and verify it with a code.
- Show recovery codes so users can get back in if they lose the device.
- Manage devices — list them, set a default, and remove one.
Before you start: elevated access tokens
registerTotpMfaDevice and deleteMfaDevice (below) both require an elevated access token — TokenScope.Credentiallink and TokenScope.Credentialunlink respectively — with no fallback. Calling either directly returns a 403 (Elevated access token required) unless the user already holds one.
Check first with checkStepUpAuth({ scope }). If it’s required, re-verify the user with an existing credential (email OTP shown here) and pass the scope in requestedScopes — the resulting elevated token is picked up automatically by the gated call that follows.
- TypeScript
Enrolling a TOTP device
registerTotpMfaDevice returns { id, secret, uri }. Render uri as a QR code (with your preferred QR library) and show secret as a manual-entry fallback. The user scans it, then enters the 6-digit code so you can verify with authenticateTotpMfaDevice.
- TypeScript
- React
Showing recovery codes
After enrolling, show the user their recovery codes once and record that they saw them withacknowledgeRecoveryCodes.
- TypeScript
- React
Managing devices
List enrolled devices, set a default, and remove one.- TypeScript
- React
Handling errors
See also
- Step-up authentication — require MFA before a sensitive action
- Post-login user setup — prompt for MFA enrollment when it’s required
- Email & SMS OTP sign-in — the sign-in step before MFA