---
title: "Finish passkey enrolment with the authenticator's attestation. (Roles: user)"
method: POST
path: "/auth/2fa/webauthn/register"
tags: ["Authentication"]
---

# Finish passkey enrolment with the authenticator's attestation. (Roles: user)

`POST /auth/2fa/webauthn/register`

The mutating half of the ceremony, and the ONLY place a step-up proof is required when adding a passkey to an account that already has 2FA: send exactly one of totp_code, recovery_code or webauthn_assertion alongside the attestation. First-time enrolment on an unprotected account needs no proof.

## Request body

- TwoFactorRegisterPayload
  - `attestation` object, required — The authenticator's response to the register-options challenge.
  - `name` string — User-visible label for the passkey. Defaults to "Passkey".
  - `totp_code` string
  - `recovery_code` string
  - `webauthn_assertion` object

## Response `200`

Success

- TwoFactorRegisterResponse
  - `credential` TwoFactorPasskey
    - `credential_id` string
    - `name` string
    - `created_at` string, date-time
    - `last_used_at` string, date-time
  - `recovery_codes` string[] — Same exactly-once rule as TwoFactorEnrollResponse.
  - `token` string — Present only when this passkey is what enabled 2FA.

## Other responses

- `400` — Error
- `429` — Too many failed second-factor attempts

## Changes

- **2026-09-01** `37a21589e770` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/ludo/apis/ludo-ai-api/changes/auth/2fa/webauthn/register/post.md)

---

[API](https://skmtc.dev/ludo/apis/ludo-ai-api.md) · [All operations](https://skmtc.dev/ludo/apis/ludo-ai-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ludo/ludo-ai-api/revisions/8c2e600e07d4/schema)
