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

# Authentication

> Create a Lumos API token, send it with every v1 request, and understand what it is allowed to do.

Lumos API v1 authenticates with a bearer token. Send it on every request:

```bash theme={null}
curl -s 'https://api.lumos.com/v1/apps' \
  --header 'Authorization: Bearer lsk_your_token'
```

Tokens start with `lsk_`. There's no cookie, session, or refresh step. The token alone
authenticates each request.

## Create a token

1. In Lumos, go to [**Settings → API Tokens**](https://app.lumosidentity.com/settings/api_tokens).
2. Click **"Add"**.
3. Enter a name and a description.
4. Click **"Add"**.
5. Copy the token value.
6. Store the token as a secret that your automation can read.

Lumos shows the value once, when you create the token. If you lose it, create a new token. Then
delete the old one.

> [!WARNING]
>
> Treat a token like a password. Keep it out of source control, browser code,
> and CI logs. Anything that holds the token can act as the user who created it.

## What a token is allowed to do

A token inherits the permissions of the user who created it. A call returns what that user could
see in the Lumos UI, and nothing more.

If the admin who created a token later loses a role, the token loses that role's access too.
Automation that depended on that access starts to fail.

A read-only token works differently. It can read what a Read Only Admin can, whatever roles its
creator has, and it can't make changes.

Create service automation tokens as a Lumos user that exists only for automation. A token that
belongs to a person can lose access when that person changes teams or leaves.

On read endpoints that support `expand`, Lumos also checks permissions per field, as
[Requesting fields with `expand`](https://docs.lumos.com/reference/v1/overview#requesting-fields-with-expand) describes.

## Telling the failures apart

| Status | What to do |
| - | - |
| `401` | Check the header format. Then check that the token still exists. |
| `403` | Grant the missing role, or use a token from a user who has that role. |
| `404` | Check the ID and the organization that it came from. |

[Status codes](https://docs.lumos.com/reference/v1/errors.md#status-codes) covers every status the API returns.

## Rate limits

Lumos limits each organization to 100 requests per second and 4,000 requests per minute. Every
request made with any of your organization's API tokens counts toward the same limits, so spreading
requests across more tokens doesn't raise them. A request without a token counts toward a limit for
its IP address. Each limit covers a moving window of time.

While a limit applies, every response includes these headers, not only a `429`:

| Header | Meaning |
| - | - |
| `X-RateLimit-Limit` | Requests allowed in the current window. |
| `X-RateLimit-Remaining` | Requests left in the current window. |
| `X-RateLimit-Reset` | The Unix time, in seconds, when the window resets. The value can include a fraction. |
| `Retry-After` | Seconds until the window resets. On a `429`, wait this long before you retry. |

On a successful response, the headers describe the shortest window. On a `429`, they describe the limit you went
over.

A request over the limit returns `429`, with `code` set to `rate_limited`. Wait the number of
seconds in `Retry-After`, plus a small random delay so that parallel clients don't all retry at
once. When you read in bulk, use larger pages instead of more requests. If you need a higher limit,
contact your Lumos representative.
