# Register a Passkey

The browser's answer to the registration's options: verified, and registered as one of your passkeys.

## Overview

- `ceremonyId`: from [Registration Options](https://docs.aureahub.com/docs/passkey-registration-options.md). `name`: your label, 1 to 100 characters. `credential`: the new credential's `toJSON()` (RegistrationResponseJSON).
- `stepUpToken`: for a passkey after your first — a `passkey.register` step-up of a passkey you already have ([The Step-Up](https://docs.aureahub.com/docs/guide-passkeys.md)). Required where your tenant's step-up mode is `enforce`; in `log` the right one is used, and a missing or wrong one refuses nothing. Your first passkey needs none.
- `201` with the passkey, which belongs to the relying party its options named: it is used there only ([Your Own Passkey Address](https://docs.aureahub.com/docs/guide-passkeys.md)). Written to your tenant's audit trail as `passkey.registered` [Coming soon, upon request](https://docs.aureahub.com/docs/feature-availability.md).
- Checked in this order, nothing registered when one fails: `503` `PASSKEYS_NOT_CONFIGURED`; `400` `PASSKEY_NAME_INVALID`; `400` `PASSKEY_CHALLENGE_INVALID` (options unknown, used, expired, or another user's); for a next passkey, `403` `STEP_UP_REQUIRED` or `STEP_UP_INVALID` where the step-up is enforced; `409` `PASSKEY_LIMIT` (10 active); `400` `PASSKEY_REGISTRATION_INVALID` (the answer does not verify: a web address that is not one of the options' relying party — Aurea's, or your passkey address's origins —, another challenge, no user verification); `409` `PASSKEY_IN_USE` (a credential is registered once).
- 20 requests per minute per client IP.

## Endpoint

### `POST /v1/auth/passkeys`

Authentication: bearer token required.

Registers a passkey from the authenticator's answer to the registration options.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ceremonyId` | string (uuid) | yes | `ceremonyId` of the registration's options |
| `name` | string | yes | Your label for it, 1–100 characters |
| `credential` | object | yes | The new credential's `toJSON()`: RegistrationResponseJSON |
| `stepUpToken` | string | no | A `passkey.register` step-up token, for a passkey after your first; 1–200 characters |

**Responses**

`201` Registered

```json
{
  "id": "3c8e1f6a-2d4b-4e7f-9a15-6b0c2d8e4f71",
  "name": "Work laptop",
  "status": "active",
  "deviceType": "multiDevice",
  "backedUp": true,
  "transports": ["hybrid", "internal"],
  "createdAt": "2026-10-14T08:02:11.512Z",
  "lastUsedAt": null,
  "revokedAt": null,
  "revokeReason": null
}
```

`400` Options spent

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "This registration's challenge is unknown, used or expired: ask for new options",
  "details": { "code": "PASSKEY_CHALLENGE_INVALID" }
}
```

`400` Did not verify

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "The authenticator's answer did not verify for this registration",
  "details": { "code": "PASSKEY_REGISTRATION_INVALID" }
}
```

`403` Step-up required

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "Confirm this with your passkey: ask POST /v1/auth/step-up/options for this action, then send its stepUpToken",
  "details": {
    "code": "STEP_UP_REQUIRED",
    "action": "passkey.register",
    "tenantId": "6f1e2d3c-4b5a-4968-8776-a5b4c3d2e1f0"
  }
}
```

`409` Limit

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "At most 10 active passkeys: revoke one first",
  "details": { "code": "PASSKEY_LIMIT" }
}
```

`409` Registered already

```json
{
  "statusCode": 409,
  "error": "ConflictError",
  "message": "This passkey is registered already: a passkey is registered once",
  "details": { "code": "PASSKEY_IN_USE" }
}
```

**Example request**

```bash
curl -X POST https://api.aureahub.com/v1/auth/passkeys \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ceremonyId": "b7d1e4a2-6c3f-4a89-9e05-2f8c1d7b3a64",
    "name": "Work laptop",
    "credential": {
      "id": "AkuuQ3HZmehDc7su8X9U7g6kRKc",
      "rawId": "AkuuQ3HZmehDc7su8X9U7g6kRKc",
      "type": "public-key",
      "response": {
        "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwi…",
        "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVi…",
        "transports": ["hybrid", "internal"]
      },
      "clientExtensionResults": { "credProps": { "rk": true } },
      "authenticatorAttachment": "platform"
    }
  }'
```

---

Web version: https://docs.aureahub.com/#passkey-register
