API Reference

Registration

API endpoints for registering a WebAuthn passkey credential.

The registration flow allows an authenticated user to associate a new passkey with their account. It consists of two endpoints.

Both registration endpoints require authentication. Include an Authorization: Bearer <token> header in every request.

Get registration options

Generate a WebAuthn challenge and credential creation options for the client.

POST /api/passkeys/register/options

Headers

HeaderValue
AuthorizationBearer <token>
Content-Typeapplication/json

Request body

FieldTypeRequiredDescription
app_namestringYesDisplay name of your application (shown in the authenticator UI)
app_urlstringYesFull URL of your application (used to extract the rpId)
Request
{
  "app_name": "My Application",
  "app_url": "https://example.com"
}

Response — WebAuthn PublicKeyCredentialCreationOptions

Response
{
  "challenge": "base64url-encoded-random-challenge",
  "rp": {
    "name": "My Application",
    "id": "example.com"
  },
  "user": {
    "id": "base64-encoded-user-id",
    "name": "user@example.com",
    "displayName": "John Doe"
  },
  "pubKeyCredParams": [
    { "type": "public-key", "alg": -7 },
    { "type": "public-key", "alg": -257 }
  ],
  "timeout": 60000,
  "attestation": "none",
  "authenticatorSelection": {
    "residentKey": "preferred",
    "userVerification": "preferred"
  }
}

The alg values correspond to:

  • -7 — ES256 (ECDSA with SHA-256, Elliptic Curve P-256)
  • -257 — RS256 (RSASSA-PKCS1-v1_5 with SHA-256)

Register a passkey

Submit the credential created by the browser to store the passkey in the database.

POST /api/passkeys/register

Headers

HeaderValue
AuthorizationBearer <token>
Content-Typeapplication/json

Request body

FieldTypeRequiredDescription
labelstringNoHuman-readable name for this passkey (e.g. "MacBook Touch ID")
idstringYesBase64url-encoded credential ID from PublicKeyCredential.id
rawIdstringYesBase64-encoded raw credential ID from PublicKeyCredential.rawId
typestringYesMust be "public-key"
response.clientDataJSONstringYesBase64-encoded client data JSON
response.attestationObjectstringYesBase64-encoded attestation object
Request
{
  "label": "MacBook Touch ID",
  "id": "credential-id-base64url",
  "rawId": "credential-id-base64",
  "type": "public-key",
  "response": {
    "clientDataJSON": "base64-encoded-client-data-json",
    "attestationObject": "base64-encoded-attestation-object"
  }
}

Response200 OK with the created passkey resource

Response
{
  "passkey": {
    "id": 1,
    "label": "MacBook Touch ID",
    "credential_id": "base64-encoded-credential-id",
    "created_at": "2024-01-15T10:30:00.000000Z"
  }
}
The challenge and public_key fields are stored in the database but not returned in the response for security reasons.