# Authentication

> How to send an API key, which scopes a key needs, the master key, ephemeral keys for end users, and 401 versus 403.

Every request carries a credential in a header:

```bash title="curl"
curl https://api.lumavox.ai/v1/voices -H "Authorization: Bearer $API_KEY"
```

`X-API-Key: <key>` works too, if a client cannot set `Authorization`. Every endpoint needs one except `GET /health` and a template's example images.

Create, scope and revoke keys in the console at https://app.lumavox.ai, under **API keys**. Treat a key as an opaque string.

## Keep your key on your server

A key in browser JavaScript or a mobile app is visible to anyone who opens developer tools, and it spends your organisation's credit until you revoke it. Call the API from your backend and pass the results — audio, images, text — on to your users.

When a user's own device has to talk to the API directly — a live conversation with an agent — your server mints that user an [ephemeral key](#ephemeral-keys-for-end-users) instead.

## Scopes

A key holds a list of scopes, and each endpoint needs one of them. Scopes come in two families.

**Capability scopes** let a key use a capability, and spend credit doing it:

| Scope | Grants |
|---|---|
| `tts` | speech: `POST /v1/tts`, `POST /v1/audio`, and reading voices |
| `agent` | reading agents and knowledge, and managing end users; the only scope an ephemeral key carries |
| `tokens` | minting, listing and revoking ephemeral keys |
| `assets` | reading your library and uploading into it |
| `image` | `POST /v1/images` |
| `video` | `POST /v1/videos` |
| `stt` | transcription: `POST /v1/stt` and `POST /v1/transcriptions` |
| `skybox` | `POST /v1/skybox` |

**Management scopes** change what your organisation owns. They are separate words on purpose, so a key that may *use* a capability cannot also rewrite it:

| Scope | Grants |
|---|---|
| `agent:write` | creating, editing and deleting agents, their organisation-wide defaults, and knowledge |
| `voices:write` | uploading, designing, editing and deleting voices |
| `assets:write` | renaming, moving and deleting assets, and the folder tree |
| `usage:read` | your organisation's usage report and credit balance |

Reads stay on the capability scope: a key holding `agent` can list agents and read their configuration, because it has to find the ones it may talk to.

A few endpoints need no scope at all. `GET /v1/token` answers any valid key. `GET /v1/generations` answers any key, and lists only the capabilities that key holds. A template is used with the scope of what it makes — an image template needs `image`.

## The master key

Your organisation's master key, in the console, holds no scopes and passes every check. You can read it again in the console at any time. It is the quickest way to try things; prefer a key scoped to what it does for anything running in production, so a leaked key can do as little as possible.

## 401 or 403

| Status | `error.code` | Means | What to do |
|---|---|---|---|
| `401` | `unauthenticated` | no credential, or one that is invalid, revoked or expired | check the header and the key |
| `403` | `forbidden` | the credential is valid, but not for this endpoint | use a key with the scope the message names |

A key limited to `tts` gets **403** from `POST /v1/images`, not 401: the key is fine, its scopes are not. The message names the missing scope and lists what the key does grant:

```json title="Response — 403"
{
  "error": {
    "code": "forbidden",
    "message": "This API key does not have the 'image' scope. It grants: tts.",
    "request_id": "8f3c2a1b9d4e5f60",
    "issues": []
  }
}
```

A path that does not exist answers **404** `not_found`, and a method a path does not take **405** `method_not_allowed`, with an `Allow` header naming the methods it does — whatever the credential.

**A deleted organisation's keys get 403** on every endpoint, saying so, and its ephemeral keys are revoked at once. Its data is kept for 90 days from the deletion, during which support can restore it, and is then erased.

## Ephemeral keys for end users

An **ephemeral key** is a short-lived credential for one of your end users — the people your agents talk to. Your server mints it with `POST /v1/ephemeral-keys` (a key holding `tokens`, and `agent`), and hands only the ephemeral key to that person's browser or app. It:

- carries only the `agent` scope, and reaches only that end user's conversations;
- is **prepaid**: its `credit_limit_micros` is set aside from your balance when it is minted, and what it does not spend comes back when it expires, runs out or is revoked;
- expires on its own, and can be revoked at any time with `DELETE /v1/ephemeral-keys/{key_id}`.

The conversation routes — `/v1/agent/*` and the [WebSocket](https://docs.lumavox.ai/agents/websocket.md) — accept **only** an ephemeral key. An API key there gets **403**, and an ephemeral key anywhere else gets **403** too — except `GET /v1/token`, which describes it. [End users and their keys](https://docs.lumavox.ai/agents/end-users.md) covers minting in full.

## Which credential am I using?

`GET /v1/token` describes the credential you call it with — useful when a session starts, or to check a key you were handed.

```bash title="curl"
curl https://api.lumavox.ai/v1/token -H "Authorization: Bearer $API_KEY"
```

For an API key:

```json title="Response"
{
  "kind": "api_key",
  "name": "Production server",
  "scopes": ["tts", "image"],
  "is_master": false,
  "created_at": "2026-09-01T12:00:00.000Z"
}
```

For an ephemeral key, it says what that key has spent so far and what it has left:

```json title="Response"
{
  "kind": "ephemeral",
  "scopes": ["agent"],
  "credit_limit_micros": 50000000,
  "credits_spent_micros": 12400000,
  "credits_remaining_micros": 37600000,
  "expires_at": "2026-10-22T10:30:00.000Z",
  "expires_in_seconds": 3240,
  "agent_ids": null,
  "end_user_id": "eu_…"
}
```

Read it when a session starts and after a response — not on a timer.

## Related

- [Errors and limits](https://docs.lumavox.ai/errors.md) — every status code, and the rate limits.
- [End users and their keys](https://docs.lumavox.ai/agents/end-users.md) — minting ephemeral keys.
- [API reference: ephemeral keys](https://docs.lumavox.ai/reference/ephemeral-keys.md)
