
# Listar los autenticadores de un usuario

`GET /v1/users/{user_id}/authenticators` · permiso `users:read`

Lista los autenticadores (claves de acceso, TOTP, SMS, correo electrónico y factores push) de un usuario en una sola página, incluidos los revocados en los últimos 90 días, ordenados por fecha de creación. El número de autenticadores por usuario está acotado, por lo que la lista no tiene `limit`, `after`, `before` ni `order`, y `list_metadata` siempre tiene valor `null`. Solo se devuelven metadatos: nunca claves públicas, IDs de credenciales, secretos TOTP ni códigos de recuperación.

## Ámbito de organización

Indique `org_id` para construir una vista de diagnóstico de miembros para un administrador de la organización. La clave también necesita entonces el permiso `organizations:read`; sin él, la solicitud falla con `403 insufficient_permissions` antes de leer nada. Si el usuario no es miembro de esa organización (no tiene una membresía `invited`, `active` o `suspended`), la solicitud falla con `404 not_found`, la misma respuesta que para un usuario desconocido. Si el usuario es miembro, solo se muestran la clase de cada autenticador y si hay MFA inscrita: solo se listan los autenticadores activos, y `label`, `last_used_at`, `revoked_at`, `revoked_by` y `revoke_reason` son `null` y `synced` es `false`, porque los datos del dispositivo de la persona fuera de la organización no le corresponden. La MFA está inscrita cuando un autenticador activo tiene el `role` `second_factor` o `both`. Sin `org_id`, la respuesta no cambia.

## Solicitud

| Parámetro | En | Obligatorio | Descripción |
|---|---|---|---|
| `user_id` | ruta | sí | ID del usuario, con el prefijo `usr_`. |
| `org_id` | consulta | no | ID de la organización, con el prefijo `org_`. Limita la vista a esa organización; consulte [Ámbito de organización](#ámbito-de-organización). Requiere `organizations:read`. |

## Respuesta

`200 OK`. `data` contiene los autenticadores ordenados por fecha de creación; `list_metadata` siempre tiene valor `null` porque la lista no está paginada. Los campos vacíos son `null`.

Cuando la clave no tiene el permiso `users:read_pii`, `label` se reduce a iniciales (`A. L.`).

```json
{
  "data": [
    {
      "id": "cred_0a1b2c3d4e5f6g7h8j9k0m1n2p",
      "type": "webauthn",
      "role": "both",
      "label": "Laptop",
      "status": "active",
      "synced": true,
      "created_at": "2026-01-15T09:30:00Z",
      "last_used_at": "2026-02-01T08:00:00Z",
      "revoked_at": null,
      "revoked_by": null,
      "revoke_reason": null
    }
  ],
  "list_metadata": {
    "before": null,
    "after": null
  }
}
```

`type`: `webauthn`, `totp`, `sms`, `email`, `push` · `role`: `first_factor`, `second_factor`, `both` · `status`: `pending`, `active`, `revoked`, `clone_suspected`

## Errores

Cada error es un cuerpo `application/problem+json` con un `code` estable.

| HTTP | `code` | Cuándo |
|---|---|---|
| 404 | `not_found` | El usuario no existe en este entorno (o el ID está mal formado), o se indica `org_id` y el usuario no es miembro de esa organización. |
| 401 | `unauthenticated` | La clave de API falta, no es válida o fue revocada. |
| 403 | `insufficient_permissions` | La clave no tiene el permiso `users:read`, o se indica `org_id` y la clave no tiene `organizations:read`. |
| 429 | `rate_limited` | Se superó el límite de frecuencia; respete `Retry-After`. |
| 503 | `service_unavailable` | Una dependencia no está disponible temporalmente; reintente más tarde. |

## Ejemplo

```bash
curl https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p/authenticators \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

## 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.
