List a user's authenticators

GET /v1/users/{user_id}/authenticators · permission users:read

Lists the authenticators (passkeys, TOTP, SMS, email and push factors) of a user in one page, including those revoked in the last 90 days, ordered by creation time. The number of authenticators per user is bounded, so the list has no limit, after, before or order, and list_metadata is always null valued. Only metadata is returned: never public keys, credential ids, TOTP secrets or recovery codes.

Organization scope

Pass org_id to build a member diagnostics view for an organization admin. The key then also needs the organizations:read permission; without it the request fails with 403 insufficient_permissions before anything is read. If the user is not a member of that organization (no invited, active or suspended membership), the request fails with 404 not_found, the same response as for an unknown user. If the user is a member, only the class of each authenticator and whether MFA is enrolled are shown: only active authenticators are listed, and label, last_used_at, revoked_at, revoked_by and revoke_reason are null and synced is false, because the person's device details outside the organization do not belong to it. MFA is enrolled when an active authenticator has the role second_factor or both. Without org_id the response is unchanged.

Request

Parameter In Required Description
user_id path yes User id, prefixed usr_.
org_id query no Organization id, prefixed org_. Limits the view to that organization; see Organization scope. Needs organizations:read.

Response

200 OK. data holds the authenticators ordered by creation time; list_metadata is always null valued because the list is not paginated. Empty fields are null.

When the key lacks the users:read_pii permission, label is reduced to initials (A. L.).

{
  "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

Errors

Every error is an application/problem+json body with a stable code.

HTTP code When
404 not_found The user does not exist in this environment (or the id is malformed), or org_id is given and the user is not a member of that organization.
401 unauthenticated The API key is missing, invalid or revoked.
403 insufficient_permissions The key lacks the users:read permission, or org_id is given and the key lacks organizations:read.
429 rate_limited The rate limit was exceeded; honor Retry-After.
503 service_unavailable A dependency is temporarily unavailable; retry later.

Example

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

Personal data

This endpoint carries personal data: credentials. Personal data in the KeenAuth APIs describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.