
# Get a user

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

Returns one user. A user of another environment, a user that does not exist and a user that has been deleted all return `404`; existence is never disclosed across environments.

## Request

| Parameter | In | Required | Description |
|---|---|---|---|
| `user_id` | path | yes | User id, prefixed `usr_`. |
| `include` | query | no | Set to `deleted` to get a tombstone for a deleted user instead of `404`. |

With `include=deleted`, a deleted user returns `410` with `deleted_at`, `deletion_id`, `backups_purged_by` (the date by which the data is purged from backups) and, for a merged user, `merged_into`; a user that never existed still returns `404`.

## Response

`200 OK`. The body is the user object. The `ETag` header carries the user version.

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.

```json
{
  "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
}
```

## 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). |
| 410 | `user_deleted` | The user was deleted and `include=deleted` was requested; the body carries `deleted_at`, `deletion_id`, `backups_purged_by` and, for a merged user, `merged_into`. |
| 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

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

## Personal data

This endpoint carries personal data: end-user profile. [Personal data in the KeenAuth APIs](/docs/policies/personal-data) 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.
