> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pacifica.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Finish WebAuthn Registration

> This endpoint allows users to finish registering a passkey or security key.

```http theme={null}
POST /api/v1/account/2fa/webauthn/register/finish
```

Finishes registering a passkey or a security key. Call it after [Begin WebAuthn registration](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor/begin-webauthn-registration.md). When this call succeeds, [two-factor authentication](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor) is on.

Pacifica accepts passkeys only from the Pacifica app. See [Passkeys and security keys](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor#passkeys-and-security-keys).

#### Operation Type (for Signing)

| Header Field | Type | Content |
| - | - | - |
| `"type"` | string | `"finish_webauthn_registration"` |

#### Request Body

<table><thead><tr><th width="176">Field</th><th width="98">Type</th><th width="95">Need</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>`"account"`</td><td>string</td><td>required</td><td>User's wallet address</td><td>`42trU9A5...`</td></tr><tr><td>`"signature"`</td><td>string</td><td>required</td><td>Cryptographic signature</td><td>`5j1Vy9Uq...`</td></tr><tr><td>`"timestamp"`</td><td>integer</td><td>required</td><td>Current timestamp in milliseconds</td><td>`1716200000000`</td></tr><tr><td>`"challenge_id"`</td><td>string</td><td>required</td><td>Challenge ID (UUID) from Begin WebAuthn registration</td><td>`45c48cce-2e2d-4fbd-8f3b-7a1c9e0d5b62`</td></tr><tr><td>`"credential"`</td><td>object</td><td>required</td><td>The credential from `navigator.credentials.create()` as JSON, with binary values as base64url strings. Not part of the signed payload</td><td>See below</td></tr><tr><td>`"expiry_window"`</td><td>integer</td><td>optional</td><td>Signature expiry in milliseconds</td><td>`30000`</td></tr></tbody></table>

```json theme={null}
{
  "account": "42trU9A5...",
  "signature": "5j1Vy9Uq...",
  "timestamp": 1716200000000,
  "challenge_id": "45c48cce-2e2d-4fbd-8f3b-7a1c9e0d5b62",
  "credential": {
    "id": "pQx3...",
    "rawId": "pQx3...",
    "type": "public-key",
    "response": {
      "attestationObject": "o2NmbXRk...",
      "clientDataJSON": "eyJ0eXBl..."
    }
  },
  "expiry_window": 30000
}
```

Sign this request with the account's own key. Agent wallets cannot sign it. The account must be a main account.

This call needs no proof. Begin WebAuthn registration already checked it.

The challenge works once. If this call fails, start again with Begin WebAuthn registration.

#### Signing

Sign `challenge_id` as the `data` object. Do not sign `credential`. For the request above, the message to sign is:

```json theme={null}
{"data":{"challenge_id":"45c48cce-2e2d-4fbd-8f3b-7a1c9e0d5b62"},"expiry_window":30000,"timestamp":1716200000000,"type":"finish_webauthn_registration"}
```

#### Response

* Status 200: Passkey or security key added

```json theme={null}
{
  "success": true,
  "data": {
    "recovery_keys": []
  },
  "error": null,
  "code": null
}
```

| Field | Type | Description |
| - | - | - |
| `'recovery_keys'` | array | New [recovery keys](https://docs.pacifica.fi/api-documentation/api/rest-api/two-factor#recovery-keys). 10 keys for your first factor. Empty when 2FA was already on |

Pacifica shows recovery keys only once. Store them somewhere safe.

* Status 400: Invalid request parameters or signature
* Status 401: The credential is not valid, or the challenge is unknown, expired, or already used
* Status 403: The account is a subaccount, or it does not exist
* Status 422: The registration does not fit the account. The `error` field says why:

| `error` | Meaning |
| - | - |
| `credential is already registered` | This passkey or security key is already a factor |
| `the authenticator must verify the user with a PIN or biometric` | The authenticator did not verify the user |
| `two-factor settings changed. Start again.` | A factor change ended this registration |
| `a user can have at most 8 factors` | The account already has 8 factors |

* Status 500: Internal server error
* Status 503: The two-factor service is unavailable. Retry later

#### Code Example (Python)

```python theme={null}
import requests

payload = {
    "account": "42trU9A5...",
    "signature": "5j1Vy9Uq...",
    "timestamp": 1716200000000,
    "challenge_id": "45c48cce-2e2d-4fbd-8f3b-7a1c9e0d5b62",
    "credential": credential  # from navigator.credentials.create() in the Pacifica app
}

response = requests.post(
    "/api/v1/account/2fa/webauthn/register/finish",
    json=payload,
    headers={"Content-Type": "application/json"}
)

data = response.json()
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.