---
title: "Create a new challenge for a MFA factor."
method: POST
path: "/factors/{factorId}/challenge"
tags: ["user"]
---

# Create a new challenge for a MFA factor.

`POST /factors/{factorId}/challenge`

## Path parameters

- `factorId` string, uuid, required

## Request body

- object
  - `channel` 'sms' | 'whatsapp'

## Response `200`

A new challenge was generated for the factor. Use `POST /factors/{factorId}/verify` to verify the challenge.

- union
  - TOTPPhoneChallengeResponse
    - `id` string, uuid, required — ID of the challenge.
    - `type` 'totp' | 'phone', required — Type of the challenge.
    - `expires_at` integer, required — UNIX seconds of the timestamp past which the challenge should not be verified.
  - WebAuthnChallengeResponse
    - `id` string, uuid, required — ID of the challenge.
    - `type` 'webauthn', required — Type of the challenge.
    - `expires_at` integer — UNIX seconds of the timestamp past which the challenge should not be verified.
    - `webauthn` union, required
      - object
        - `type` 'create', required — Credential creation operation
        - `credential_options` object, required
          - `publicKey` CredentialCreationOptions, required — PublicKeyCredentialCreationOptions for WebAuthn registration
            - `rp` object, required
              - …
            - `user` object, required
              - …
            - `challenge` string, base64url, required — A challenge to be signed by the authenticator
            - `pubKeyCredParams` object[], required — List of supported public key algorithms
              - …
            - `timeout` integer — Time (in milliseconds) that the caller is willing to wait for the call to complete
            - `excludeCredentials` PublicKeyCredentialDescriptor[] — List of credentials to exclude (prevent re-registration)
              - …
            - `authenticatorSelection` object
              - …
            - `attestation` 'none' | 'indirect' | 'direct' | 'enterprise' — Attestation conveyance preference
            - `attestationFormats` string[] — Preferred attestation statement formats
            - `hints` string[] — Hints for the browser about what types of authenticators to show
            - `extensions` object — WebAuthn extensions to enable
      - object
        - `type` 'request', required — Credential request operation
        - `credential_options` object, required
          - `publicKey` CredentialRequestOptions, required — PublicKeyCredentialRequestOptions for WebAuthn authentication
            - `challenge` string, base64url, required — A challenge to be signed by the authenticator
            - `timeout` integer — Time (in milliseconds) that the caller is willing to wait for the call to complete
            - `rpId` string — Relying Party ID
            - `allowCredentials` PublicKeyCredentialDescriptor[] — List of acceptable credentials for authentication
              - …
            - `userVerification` 'required' | 'preferred' | 'discouraged' — User verification requirement
            - `hints` string[] — Hints for the browser about what types of authenticators to show
            - `extensions` object — WebAuthn extensions to enable

## Other responses

- `400` — HTTP Bad Request response. Can occur if the passed in JSON cannot be unmarshalled properly or when CAPTCHA verification was not successful. In certain cases can also occur when features are disabled on the server (e.g. sign ups). It may also mean that the operation failed due to some constraint not being met (such a user already exists for example).
- `429` — HTTP Too Many Requests response, when a rate limiter has been breached.

## Changes

- **2026-04-28** `d3f7d49a0bd6` — 1 warning
  - removed the request property `webauthn`
- **2025-09-24** `a222d9459767` — 1 breaking, 2 warning, 2 info
  - the response property `oneOf[#/components/schemas/WebAuthnChallengeResponse]/expires_at` became optional for the status `200`
  - removed the optional property `oneOf[#/components/schemas/WebAuthnChallengeResponse]/credential_creation_options` from the response with the `200` status
  - removed the optional property `oneOf[#/components/schemas/WebAuthnChallengeResponse]/credential_request_options` from the response with the `200` status
  - added the new optional request property `webauthn`
  - …1 more
- **2025-02-07** `4d0f1a6c1ad9` — 1 breaking, 1 info
  - the `oneOf[#/components/schemas/WebAuthnChallengeResponse]/credential_creation_options/user/factors/items/web_authn_credential` response's property type/format changed from `jsonb`/`` to `string`/`` for status `200`
  - added the optional property `error_code` to the response with the `400` status
- …earlier changes not shown

[Full history](https://skmtc.dev/supabase/apis/supabase-auth-rest-api/changes/factors/:factorId/challenge/post.md)

---

[API](https://skmtc.dev/supabase/apis/supabase-auth-rest-api.md) · [All operations](https://skmtc.dev/supabase/apis/supabase-auth-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/supabase/supabase-auth-rest-api/revisions/2e2a74a7459f/schema)
