Docs

Finish passkey registration

POST
/users/{user_id}/passkeys/registrations/{registration_id}

Verifies the attestation against the ceremony started by POST /users/{user_id}/passkeys/registrations and persists the new credential. A rejected attestation counts against the ceremony's failure budget and the ceremony stays open for a retry. An expired ceremony surfaces as att.stale_challenge; an unknown or already-consumed registration id surfaces as att.not_found.

Authorization

oauth2 user.write
headerAuthorizationBearer <token>

Scope: user.write

Path Parameters

user_id*string

The unique identifier of the user.

Match^user_[a-zA-Z0-9_-]+$
registration_id*string

The ceremony identifier returned by begin.

Request Body

application/json
  1. body

Request to complete a WebAuthn registration ceremony.

attestation*

The WebAuthn AttestationResponse object from navigator.credentials.create().

name?string

Label for the credential in passkey management surfaces. Optional: when omitted, a name is derived from the credential itself.

Response Body

The passkey was registered

application/json
  1. response

The registered passkey.

id*string

The unique identifier of the passkey.

name*string

The name of the passkey.

created_at*string

The timestamp when the passkey was created.

Formatdate-time
Example Request
import { createZitadelClient } from "@zitadel/api/client";const client = createZitadelClient({  baseUrl: process.env.ZITADEL_URL ?? "http://localhost:8080",  token: process.env.ZITADEL_PROJECT_SECRET!, // server-side only});const userPasskeyRegistration = await client.finishUserPasskeyRegistration(  "user_01KWH3B72K7M7F0N9WD3P2E4YM",  "att_01J0Z9KX7Y0Q2Y7JX5M9K2YF3C",  { attestation: {} },);
Example Response
{  "id": "string",  "name": "string",  "created_at": "2019-08-24T14:15:22Z"}

Was this helpful?