> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The User object

> A person in your Lumos organization, the fields v1 returns, and how to read and change their Lumos roles.

A user is a person in your Lumos organization, and one kind of identity. Users hold
[accounts](https://docs.lumos.com/reference/v1/objects/account.md) on your [apps](https://docs.lumos.com/reference/v1/objects/app.md), and an
account's `user_id` is the `id` of the user it belongs to.

v1 reads users but doesn't create or edit them. The only change v1 makes to a user is through the
roles endpoints, which add and remove the user's Lumos roles.

```json The User object theme={null}
{
  "id": "3c4d5e6f-7081-9012-cdef-123456789012",
  "email": "jane.smith@example.com",
  "given_name": "Jane",
  "family_name": "Smith",
  "status": "active",
  "custom_attributes": null
}
```

## Attributes

| Field | Type | Description |
| - | - | - |
| `id` | string | Unique identifier for the user. Always present. |
| `email` | string or null | The user's email. |
| `given_name` | string or null | The user's given name. |
| `family_name` | string or null | The user's family name. |
| `status` | string or null | One of `staged`, `active`, `suspended`, or `inactive`. |
| `custom_attributes` | object or null | Custom attribute values, keyed by attribute label. `null` unless you pass `expand=custom_attributes`. |

[Get Current User](https://docs.lumos.com/api-reference/v1/users/get-current-user.md) returns the same object without
`custom_attributes`.

## Custom attributes

Pass `expand=custom_attributes` to [List Users](https://docs.lumos.com/api-reference/v1/users/list-users.md) or
[Get User](https://docs.lumos.com/api-reference/v1/users/get-user.md) to include `custom_attributes`. Each value carries a
`type` of `text` or `user`. A `user` value is an array of user objects. It's empty when Lumos can't
find the user it points to.

```json theme={null}
"custom_attributes": {
  "Cost Center": { "type": "text", "value": "R&D" },
  "Manager": {
    "type": "user",
    "value": [
      {
        "id": "4d5e6f70-8192-0123-def1-234567890123",
        "email": "sam.lee@example.com",
        "given_name": "Sam",
        "family_name": "Lee",
        "status": "active"
      }
    ]
  }
}
```

## Finding users

[List Users](https://docs.lumos.com/api-reference/v1/users/list-users.md) returns users sorted by name. `search`
matches a name or an email. Add `exact_match=true` to return only users whose name or email equals
`search`. A page can hold
fewer users than `page_size` while more remain, so stop only when `next_page_token` is missing or
`null`, as [Pagination](https://docs.lumos.com/reference/v1/pagination.md) describes.

[Get Current User](https://docs.lumos.com/api-reference/v1/users/get-current-user.md) returns the user who owns the calling
token. Use it to check which user a token acts as.

## Unknown and deleted users

A user ID returns `404` when it doesn't match a user in your organization, or when it belongs to a
user that Lumos has removed from your organization. [List Users](https://docs.lumos.com/api-reference/v1/users/list-users.md)
omits removed users, and requests for their accounts or roles also return `404`. No parameter
includes them.

## Accounts

[List User Accounts](https://docs.lumos.com/api-reference/v1/users/list-user-accounts.md) returns the accounts one user
holds. They're the same [Account objects](https://docs.lumos.com/reference/v1/objects/account.md) that
[List Accounts](https://docs.lumos.com/api-reference/v1/accounts/list-accounts.md) returns,
and `expand=app` adds each account's app.

## Roles

[List User Roles](https://docs.lumos.com/api-reference/v1/users/list-user-roles.md) returns the user's `id` as `user_id`
and their roles as `roles`, a list of role objects:

```json theme={null}
{
  "user_id": "3c4d5e6f-7081-9012-cdef-123456789012",
  "roles": [
    { "id": "app-admin", "label": "App Admin", "is_custom": false, "resource_type": "app" },
    {
      "id": "5e6f7081-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
      "label": "Billing Viewer",
      "is_custom": true,
      "resource_type": null
    }
  ]
}
```

| Field | Type | Description |
| - | - | - |
| `id` | string | The role's identifier. A built-in role's `id` is a kebab-case name, such as `app-admin`. A custom role's `id` is a UUID. Always present. |
| `label` | string | The role's display name, such as `App Admin`, or the name your organization gave a custom role. Always present. |
| `is_custom` | boolean | Whether the role is a custom role that your organization defined. Always present. |
| `resource_type` | string or null | The type of resource the role applies to, such as `app`. `null` for a role that applies across your organization. |

`resource_type` is one of `app`, `dashboard`, `access-policy`, `vendor`, `non-human-identity`,
`task`, or `discovered-credential`. It names a type only. The role object doesn't say which apps,
vendors, or other resources the role covers.

[Add User Role](https://docs.lumos.com/api-reference/v1/users/add-user-role.md) and
[Remove User Role](https://docs.lumos.com/api-reference/v1/users/remove-user-role.md) take the role's `id` in the path:

```bash theme={null}
curl -s -X POST 'https://api.lumos.com/v1/users/3c4d5e6f-7081-9012-cdef-123456789012/roles/app-admin' \
  --header 'Authorization: Bearer lsk_your_token'
```

`role_id` is a built-in role's `id` from the table below, or a custom role's `id` from List User
Roles. Naming a built-in role by its v0 name, such as `APP_ADMIN`, returns `400` with `code` set to
`role.id_required`.

| `id` | `label` | `resource_type` |
| - | - | - |
| `organization-admin` | Admin | `null` |
| `read-only-organization-admin` | Read Only Admin | `null` |
| `auditor` | Auditor | `null` |
| `appstore-read-only-admin` | AppStore Read Only Admin | `null` |
| `app-admin` | App Admin | `app` |
| `vendor-owner` | Vendor Owner | `vendor` |
| `vendor-agreement-owner` | Vendor Agreement Owner | `vendor` |
| `mcp-governance` | MCP Governance | `null` |
| `user` | User | `null` |

Two more built-in roles, `lumos-internal-user` and `vendor-qa-user`, are reserved for internal
Lumos use. Add User Role and Remove User Role return `403` for either one, but List User Roles
can still return them for a user Lumos assigned them to. Any other value returns `400`, including
a role's `label` and a custom role's name.

Add User Role returns `201`. When Lumos adds the role, the body has `role_added`, which is the role
object for it. When the user already holds the role, nothing changes, and the body has `message`
instead. `message` names the role by its `label`. Remove User Role returns `204` whether or not the
user held the role, so both calls are safe to retry.

Of the built-in roles, Admin and Read Only Admin can read any user's roles, and only Admin can add or
remove any role. App Admin can add or remove only the App Admin role.

## Endpoints

| Endpoint | Path |
| - | - |
| [List Users](https://docs.lumos.com/api-reference/v1/users/list-users.md) | `GET /v1/users` |
| [Get Current User](https://docs.lumos.com/api-reference/v1/users/get-current-user.md) | `GET /v1/users/current` |
| [Get User](https://docs.lumos.com/api-reference/v1/users/get-user.md) | `GET /v1/users/{user_id}` |
| [List User Accounts](https://docs.lumos.com/api-reference/v1/users/list-user-accounts.md) | `GET /v1/users/{user_id}/accounts` |
| [List User Roles](https://docs.lumos.com/api-reference/v1/users/list-user-roles.md) | `GET /v1/users/{user_id}/roles` |
| [Add User Role](https://docs.lumos.com/api-reference/v1/users/add-user-role.md) | `POST /v1/users/{user_id}/roles/{role_id}` |
| [Remove User Role](https://docs.lumos.com/api-reference/v1/users/remove-user-role.md) | `DELETE /v1/users/{user_id}/roles/{role_id}` |
