---
title: "Complete TOTP MFA enrollment"
method: POST
path: "/v1/users/{user_id}/mfa/totp/enrollment/verify"
tags: ["Users MFA"]
---

# Complete TOTP MFA enrollment

`POST /v1/users/{user_id}/mfa/totp/enrollment/verify`

## Request

- Base URL: `https://api.privy.io`
- URL: `https://api.privy.io/v1/users/{user_id}/mfa/totp/enrollment/verify`
- Auth: HTTP basic

Enrolls the authenticator from init using a code it generated.

## Path parameters

- `user_id` string, required

## Headers

- `privy-app-id` string, required: ID of your Privy app.
- `privy-user-token` string, required: Access token or custom authentication JWT for the user the request acts on.

## Request body

- TotpMfaVerifyRequestBody: Completes a TOTP MFA ceremony with a code from the authenticator.
  - `code` string, required

## Response `200`

TOTP MFA enrolled.

- MfaVerificationResponse: An MFA token and the current user after completing an MFA ceremony.
  - `token` string, required: JWT proving the user completed MFA.
  - `expires_at` integer, required: Unix timestamp in seconds when the MFA token expires.
  - `user` User, required: A Privy user object.
    - `id` string, required
    - `linked_accounts` LinkedAccount[], required
      - union: A linked account for the user.
        - object: An email account linked to the user.
          - `type` 'email', required
          - `address` string, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A phone number account linked to the user.
          - `type` 'phone', required
          - `number` string
          - `phoneNumber` string, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: An Ethereum wallet account linked to the user.
          - `type` 'wallet', required
          - `address` string, required
          - `chain_id` string
          - `chain_type` 'ethereum', required
          - `wallet_client` 'unknown', required
          - `wallet_client_type` string
          - `connector_type` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Solana wallet account linked to the user.
          - `type` 'wallet', required
          - `address` string, required
          - `chain_type` 'solana', required
          - `wallet_client` 'unknown', required
          - `wallet_client_type` string
          - `connector_type` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A smart wallet account linked to the user.
          - `type` 'smart_wallet', required
          - `address` string, required
          - `smart_wallet_type` 'safe' | 'kernel' | 'light_account' | 'biconomy' | 'coinbase_smart_wallet' | 'thirdweb' | 'nexus', required: The supported smart wallet providers.
          - `smart_wallet_version` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: An Ethereum embedded wallet account linked to the user.
          - `id` string, nullable, required
          - `type` 'wallet', required
          - `address` string, required
          - `imported` boolean, required
          - `delegated` boolean, required
          - `wallet_index` number, required
          - `chain_id` string, required
          - `chain_type` 'ethereum', required
          - `wallet_client` 'privy', required
          - `wallet_client_type` 'privy', required
          - `connector_type` 'embedded', required
          - `recovery_method` 'privy' | 'user-passcode' | 'google-drive' | 'icloud' | 'recovery-encryption-key' | 'privy-v2', required: The method used to recover an embedded wallet account.
          - `user_can_sign` boolean, required: Whether the user can unilaterally sign with this wallet.
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Solana embedded wallet account linked to the user.
          - `id` string, nullable, required
          - `type` 'wallet', required
          - `address` string, required
          - `imported` boolean, required
          - `delegated` boolean, required
          - `wallet_index` number, required
          - `chain_id` string, required
          - `chain_type` 'solana', required
          - `wallet_client` 'privy', required
          - `wallet_client_type` 'privy', required
          - `connector_type` 'embedded', required
          - `recovery_method` 'privy' | 'user-passcode' | 'google-drive' | 'icloud' | 'recovery-encryption-key' | 'privy-v2', required: The method used to recover an embedded wallet account.
          - `user_can_sign` boolean, required: Whether the user can unilaterally sign with this wallet.
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
          - `public_key` string, required
        - object: A Bitcoin SegWit embedded wallet account linked to the user.
          - `id` string, nullable, required
          - `type` 'wallet', required
          - `address` string, required
          - `imported` boolean, required
          - `delegated` boolean, required
          - `wallet_index` number, required
          - `chain_id` string, required
          - `chain_type` 'bitcoin-segwit', required
          - `wallet_client` 'privy', required
          - `wallet_client_type` 'privy', required
          - `connector_type` 'embedded', required
          - `recovery_method` 'privy' | 'user-passcode' | 'google-drive' | 'icloud' | 'recovery-encryption-key' | 'privy-v2', required: The method used to recover an embedded wallet account.
          - `user_can_sign` boolean, required: Whether the user can unilaterally sign with this wallet.
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
          - `public_key` string, required
        - object: A Bitcoin Taproot embedded wallet account linked to the user.
          - `id` string, nullable, required
          - `type` 'wallet', required
          - `address` string, required
          - `imported` boolean, required
          - `delegated` boolean, required
          - `wallet_index` number, required
          - `chain_id` string, required
          - `chain_type` 'bitcoin-taproot', required
          - `wallet_client` 'privy', required
          - `wallet_client_type` 'privy', required
          - `connector_type` 'embedded', required
          - `recovery_method` 'privy' | 'user-passcode' | 'google-drive' | 'icloud' | 'recovery-encryption-key' | 'privy-v2', required: The method used to recover an embedded wallet account.
          - `user_can_sign` boolean, required: Whether the user can unilaterally sign with this wallet.
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
          - `public_key` string, required
        - object: A curve signing embedded wallet account linked to the user.
          - `id` string, nullable, required
          - `type` 'wallet', required
          - `address` string, required
          - `imported` boolean, required
          - `delegated` boolean, required
          - `wallet_index` number, required
          - `chain_id` string, required
          - `chain_type` 'cosmos' | 'stellar' | 'sui' | 'aptos' | 'movement' | 'tron' | 'bitcoin-segwit' | 'bitcoin-taproot' | 'pearl' | 'near' | 'ton' | 'starknet' | 'xrpl', required: The wallet chain types that support curve-based signing.
          - `wallet_client` 'privy', required
          - `wallet_client_type` 'privy', required
          - `connector_type` 'embedded', required
          - `recovery_method` 'privy' | 'user-passcode' | 'google-drive' | 'icloud' | 'recovery-encryption-key' | 'privy-v2', required: The method used to recover an embedded wallet account.
          - `user_can_sign` boolean, required: Whether the user can unilaterally sign with this wallet.
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
          - `public_key` string, required
        - object: A Google OAuth account linked to the user.
          - `type` 'google_oauth', required
          - `subject` string, required
          - `email` string, required
          - `name` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Twitter OAuth account linked to the user.
          - `type` 'twitter_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `name` string, nullable, required
          - `profile_picture_url` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Discord OAuth account linked to the user.
          - `type` 'discord_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `email` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A GitHub OAuth account linked to the user.
          - `type` 'github_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `name` string, nullable, required
          - `email` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Spotify OAuth account linked to the user.
          - `type` 'spotify_oauth', required
          - `subject` string, required
          - `email` string, nullable, required
          - `name` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: An Instagram OAuth account linked to the user.
          - `type` 'instagram_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A TikTok OAuth account linked to the user.
          - `type` 'tiktok_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `name` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A LINE OAuth account linked to the user.
          - `type` 'line_oauth', required
          - `subject` string, required
          - `name` string, nullable, required
          - `email` string, nullable, required
          - `profile_picture_url` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Twitch OAuth account linked to the user.
          - `type` 'twitch_oauth', required
          - `subject` string, required
          - `username` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A LinkedIn OAuth account linked to the user.
          - `type` 'linkedin_oauth', required
          - `subject` string, required
          - `name` string
          - `email` string, nullable, required
          - `vanity_name` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: An Apple OAuth account linked to the user.
          - `type` 'apple_oauth', required
          - `subject` string, required
          - `email` string, nullable, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A custom OAuth account linked to the user.
          - `type` string, required: The ID of a custom OAuth provider, set up for this app. Must start with "custom:".
          - `subject` string, required
          - `name` string
          - `username` string
          - `email` string
          - `profile_picture_url` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A custom JWT account linked to the user.
          - `type` 'custom_auth', required
          - `custom_user_id` string, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Farcaster account linked to the user.
          - `type` 'farcaster', required
          - `fid` number, required
          - `owner_address` string, required
          - `username` string
          - `display_name` string
          - `bio` string
          - `profile_picture` string
          - `profile_picture_url` string
          - `homepage_url` string
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
          - `signer_public_key` string
        - object: A passkey account linked to the user.
          - `type` 'passkey', required
          - `created_with_browser` string
          - `created_with_os` string
          - `created_with_device` string
          - `credential_id` string, required
          - `authenticator_name` string
          - `public_key` string
          - `enrolled_in_mfa` boolean, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A Telegram account linked to the user.
          - `type` 'telegram', required
          - `telegram_user_id` string, required
          - `first_name` string, nullable
          - `last_name` string, nullable
          - `username` string, nullable
          - `photo_url` string, nullable
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: A cross-app account linked to the user.
          - `type` 'cross_app', required
          - `subject` string, required
          - `provider_app_id` string, required
          - `embedded_wallets` CrossAppEmbeddedWallet[], required
            - `address` string, required
          - `smart_wallets` CrossAppSmartWallet[], required
            - `address` string, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
        - object: An authorization key linked to the user.
          - `type` 'authorization_key', required
          - `public_key` string, required
          - `verified_at` number, required
          - `first_verified_at` number, nullable, required
          - `latest_verified_at` number, nullable, required
    - `mfa_methods` LinkedMfaMethod[], required
      - union: A multi-factor authentication method linked to the user.
        - object: A SMS MFA method.
          - `type` 'sms', required
          - `verified_at` number, required
        - object: A TOTP MFA method.
          - `type` 'totp', required
          - `verified_at` number, required
        - object: A Passkey MFA method.
          - `type` 'passkey', required
          - `verified_at` number, required
        - object: An Email MFA method.
          - `type` 'email', required
          - `verified_at` number, required
    - `created_at` number, required: Unix timestamp of when the user was created in seconds.
    - `has_accepted_terms` boolean, required: Indicates if the user has accepted the terms of service.
    - `is_guest` boolean, required: Indicates if the user is a guest account user.
    - `custom_metadata` CustomMetadata: Custom metadata associated with the user.
    - `frozen_at` integer, nullable: Unix timestamp in seconds of when the user was frozen, or `null` if not frozen. Not included in every user response.

## Changes

- **2026-10-27** `9b687835ed44`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/privy-io/apis/privy-api/changes/v1/users/:user_id/mfa/totp/enrollment/verify/post.md)

---

[API](https://skmtc.dev/privy-io/apis/privy-api.md) - [All operations](https://skmtc.dev/privy-io/apis/privy-api/llms.txt) - [OpenAPI document](https://skmtc.dev/privy-io/apis/privy-api/revisions/6a80d4be53a8?raw)
