List users
GET /v1/users · permission users:read
Lists the users of the environment with cursor pagination, newest first by default. Only filters that carry no personal data are accepted here. To look users up by email, phone number or username use Search users.
Request
| Parameter | In | Required | Description |
|---|---|---|---|
limit |
query | no | Page size, 1 to 100. Default 20. |
after |
query | no | Opaque cursor from list_metadata.after. Exclusive with before. |
before |
query | no | Opaque cursor from list_metadata.before. Exclusive with after. |
order |
query | no | asc or desc by creation time. Default desc. |
status |
query | no | active, blocked or pending_deletion. |
external_id |
query | no | Exact match on your own identifier. |
created_after |
query | no | RFC 3339 time; users created after it. |
created_before |
query | no | RFC 3339 time; users created before it. |
A cursor is only valid with the same filters and order it was issued for; otherwise the request fails with invalid_cursor.
Response
200 OK. data holds the users on the page; list_metadata.before and list_metadata.after are cursors for the previous and next page (null when there is none). No total count is returned.
Personal data is masked when the key lacks the users:read_pii permission: email becomes a***@e***.com, phone_number keeps only its last 2 digits (+**********67), name, given_name, family_name, middle_name and nickname become initials (A. L.), username keeps only its first character (a***), birthdate becomes ****-**-** and address becomes {"redacted": true}. user_metadata and app_metadata are not masked.
{
"data": [ {
"id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p",
"kind": "regular",
"status": "active",
"external_id": null,
"username": null,
"name": "Ada Lovelace",
"email": "ada@example.com",
"email_verified": true,
"phone_number": null,
"phone_verified": false,
"user_metadata": {},
"app_metadata": {},
"created_via": "admin_api",
"created_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:30:00Z",
"last_sign_in_at": null,
"deletion_requested_at": null,
"deletion_due_at": null
} ],
"list_metadata": { "before": null, "after": "<opaque cursor>" }
}
Errors
Every error is an application/problem+json body with a stable code.
| HTTP | code |
When |
|---|---|---|
| 400 | invalid_cursor |
The cursor is malformed, tampered with, or was issued for other filters. |
| 422 | validation_failed |
A query parameter is invalid (limit out of range, bad timestamp, repeated parameter). |
| 401 | unauthenticated |
The API key is missing, invalid or revoked. |
| 403 | insufficient_permissions |
The key lacks the users:read permission. |
| 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?limit=20&status=active" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
Personal data
This endpoint carries personal data: end-user profile. 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.