1. Docs
  2. API Reference
  3. Redeem a single-use recovery code to satisfy an in-flight MFA challenge

Redeem a single-use recovery code to satisfy an in-flight MFA challenge

POST/v1/identity/auth/mfa/challenge/recovery-code

Request body

  • challenge_tokenstring*

    Challenge token returned by /v1/identity/auth/login when `requires_mfa_challenge` was true.

  • codestring*

    A single-use recovery code shown during enrollment. Dashes and case are normalised server-side — `ABCD-EFGH-IJKL-MNOP` and `abcdefghijklmnop` are accepted equivalently.

  • remember_deviceboolean

    When true and the env's `mfa_trusted_device_days` > 0, issue a 'remember this device' cookie so future logins from this browser skip the MFA challenge. Default false.

Code samples

cURLJavaScriptPythonGo
curl -X POST "https://api.canopy.dev/v1/identity/auth/mfa/challenge/recovery-code" \
  -H "Content-Type: application/json" \
  -d '{
    "challenge_token": "string",
    "code": "ABCD-EFGH-IJKL-MNOP",
    "remember_device": false
  }'

Responses

200 Consumes one of the 10 recovery codes issued at enrollment. Returns the full session on success. The redeemed code is marked single-use and cannot satisfy a future challenge.
{
  "requires_application_selection": false,
  "requires_mfa_challenge": false,
  "expires_in": 0,
  "identity": {
    "id": "string",
    "email": "string",
    "first_name": "string",
    "last_name": "string"
  },
  "access_token": "string",
  "token_type": "string",
  "applications": [
    {
      "id": "string",
      "name": "string",
      "slug": "string"
    }
  ],
  "mfa_challenge": {
    "challenge_token": "string",
    "available_factors": [
      "totp"
    ],
    "expires_at": "2026-04-20T12:00:00.000Z"
  },
  "mfa_enrollment_pending": false,
  "grace_expires_at": "2026-04-20T12:00:00.000Z"
}

application/json

  • requires_application_selectionboolean*
  • requires_mfa_challengeboolean*

    True when the env requires MFA and the identity has ≥ 1 enrolled factor. The client must POST one of `/v1/identity/auth/mfa/challenge/*` with the supplied `mfa_challenge.challenge_token` to mint a session.

  • expires_innumber*
  • identityIdentityUserDto*
  • access_tokenstring
  • token_typestring
  • applicationsIdentityApplicationSummaryDto[]
  • mfa_challengeIdentityMfaChallengePromptDto
  • mfa_enrollment_pendingboolean

    True when the env requires MFA, the identity has not yet enrolled a factor, and the per-env grace timer has time on it. Session is fully issued; the client should nudge the user to enroll a factor before `grace_expires_at`.

  • grace_expires_atstring (date-time)

    Wall-clock deadline by which the identity must enroll a factor; after this, login is blocked with `mfa.enrollment_required` until an admin force-resets MFA.

401 Challenge token is missing, expired, already consumed, or locked after too many failed attempts

Returned object

On this page

Related endpoints

POSTSubmit a TOTP code to satisfy an in-flight MFA challenge
POSTGenerate WebAuthn authentication options for an in-flight MFA challenge
POSTSubmit a WebAuthn assertion to satisfy an in-flight MFA challenge
POSTTrigger an email OTP for an in-flight MFA challenge
POSTSubmit an email OTP to satisfy an in-flight MFA challenge