Complete authenticator app enrollment
/v1/auth/mfa/totp/enroll/verifyCompletes authenticator-app enrollment by checking the 6-digit code against the secret sealed in enrollment_token and storing the factor under label. The administrator's first factor also returns a one-time batch of ten recovery codes, the only way back in without the device, and clears any running grace timer. Responds 400 when the token is missing, expired, sealed for another user, or the code does not match. Rate-limited to 10 requests per minute.
Authentication
AuthorizationJWT access token. Never send alongside X-API-Key: a request carrying both is refused.
Request body
application/json
enrollment_tokenstring Required The sealed enrollment_token returned by the `start` endpoint. Carries the provisional TOTP secret server-side.
codestring Required 6-digit code from the authenticator app.
labelstring Required User-facing nickname for the factor ("iPhone 15", "Work Laptop"). Shown on the factor-management surface.
Responses
application/json
data *MfaTotpEnrollVerifyResponseDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
application/json
error *ApiErrorBodyDto
Rate limit
Returned object
curl -X POST "https://auth.canopy-io.com/v1/auth/mfa/totp/enroll/verify" \ -H "Authorization: Bearer $CANOPY_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "enrollment_token": "string", "code": "123456", "label": "iPhone 15" }'
{ "data": { "factor": { "id": "00000000-0000-0000-0000-000000000000", "type": "totp", "label": "iPhone 15", "enrolled_at": "2026-04-20T12:00:00.000Z", "last_used_at": "2026-04-20T12:00:00.000Z", "webauthn_rp_id": "acme.com" }, "recovery_codes": [ "ABCD-EFGH-IJKL-MNOP", "QRST-UVWX-YZ23-4567", "..." ], "recovery_codes_generation": 0 } }
Tell us how we can improve this guide.