
# Iniciar un registro de clave de acceso

`POST /fapi/v1/me/passkeys/registration-options` · llamado desde el host de inicio de sesión del entorno

Abre un registro de WebAuthn para el usuario autenticado desde el portal de la cuenta y devuelve las opciones que se deben pasar a `navigator.credentials.create`. Finalícelo con [`POST /fapi/v1/me/passkeys`](./register). El registro es válido durante 5 minutos, solo puede finalizarse una vez y únicamente por la sesión que lo inició. Requiere la cookie `__Host-idp_session` del usuario autenticado; si la cookie falta, ha caducado o ha sido revocada, devuelve `401 unauthenticated`. Una aplicación propia en otro origen puede enviar en su lugar su token de acceso de la API frontal (`Authorization: DPoP <token>` con una prueba DPoP; consulte [Token de acceso de la API frontal](/docs/api/fapi/front-api-token)).

La sesión debe haberse verificado en los últimos 10 minutos para una clave de acceso, o en los últimos 5 minutos para una clave de seguridad. Si el usuario ya tiene un segundo factor, la sesión también debe haberse abierto con un segundo factor (`urn:idp:acr:mfa`): una nueva clave de acceso no puede elevar la garantía de la sesión que la añade.

## Solicitud

Encabezados:

| Encabezado | Obligatorio | Descripción |
| --- | --- | --- |
| `Idp-Client` | sí | Identificador del SDK. |
| `Origin` | sí | Debe ser exactamente `https://<host de inicio de sesión>`. |
| `Content-Type` | sí | `application/json`. |

Cuerpo:

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `role` | string | sí | `passkey`: una credencial que inicia sesión por sí sola (requiere que el inicio de sesión con clave de acceso esté activado en el entorno). `security_key`: una credencial usada solo como segundo factor (requiere que el segundo factor con clave de seguridad esté activado). |

## Respuesta

`200 OK`:

```json
{
  "ceremony_id": "CQAAAAAAAAAAAAAAAAAAAA",
  "options": {"publicKey": {"challenge": "…", "rp": {"id": "example.keenauth.app", "name": "Example"}, "user": {"id": "…", "name": "ada@example.org", "displayName": "ada@example.org"}, "pubKeyCredParams": [], "timeout": 300000, "excludeCredentials": [], "authenticatorSelection": {}, "attestation": "none", "extensions": {"credProps": true}}}
}
```

Pase `options.publicKey` a `PublicKeyCredential.parseCreationOptionsFromJSON` y el resultado a `navigator.credentials.create`. `excludeCredentials` enumera las credenciales del usuario para esta parte de confianza, de modo que el mismo autenticador no se registre dos veces.

## Errores

| Estado | Código | Cuándo |
| --- | --- | --- |
| 400 | `malformed_request` | El cuerpo no es un JSON válido. |
| 400 | `unknown_field` | El cuerpo tiene un campo distinto de `role`. |
| 401 | `unauthenticated` | No hay una cookie de sesión válida. |
| 401 | `step_up_required` | La sesión es demasiado antigua o se requiere un segundo factor; vuelva a verificar con `max_age` (y, si corresponde, `acr_values`) en el encabezado `WWW-Authenticate`. |
| 403 | `origin_not_allowed` | `Origin` falta o es incorrecto. |
| 403 | `no_allowed_method` | El entorno no permite este `role`. |
| 409 | `credential_limit_reached` | El usuario ya tiene el número máximo de claves de acceso y claves de seguridad. |
| 413 | `payload_too_large` | El cuerpo es demasiado grande. |
| 415 | `unsupported_media_type` | `Content-Type` no es `application/json`. |
| 422 | `validation_failed` | `role` falta o no es `passkey` ni `security_key`. |
| 422 | `aaguid_not_allowed` | La lista de autenticadores permitidos del entorno no es válida; el registro queda bloqueado hasta que se corrija. |

## Ejemplo

```bash
curl -X POST https://example.keenauth.app/fapi/v1/me/passkeys/registration-options \
  -H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
  -H "Origin: https://example.keenauth.app" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"role": "passkey"}'
```

## Datos personales

Este endpoint contiene datos personales: credenciales. [Datos personales en las API de KeenAuth](/docs/policies/personal-data) describe qué se almacena, cuánto tiempo se conserva y cómo se elimina. No envíe categorías especiales de datos personales (salud, datos biométricos, religión, opiniones políticas, orientación sexual) en ningún campo.
