---
title: "Ключ, права и заголовки"
url: https://lumean.app/developers/docs/guide/authentication
locale: ru
description: "X-API-KEY как отдельный контур, одиннадцать предметных прав плюс wildcard, три пресета — и почему «automation» не проходит базовый сценарий целиком."
updated: 2026-10-17
sources: [get-user, post-templates, post-storage-url, get-templates-template, post-voices-cartesia-clones, post-reseller-codes, get-ai-models]
errors: ["401", "403", template-access-denied]
spec_version: 0.0.1
---

# Ключ, права и заголовки

Публичный API авторизуется одним заголовком и ничем больше. Анонимных ручек в нём нет:
каждая операция спеки требует ключа, и почти каждая называет конкретное право в собственном
описании. Исключение — каталог AI-моделей: ему подходит любой активный ключ. Страниц
справочника на одну меньше, чем операций: `PUT` и `PATCH /templates/{template}` схлопнуты
в одну (это одна операция под двумя методами), а `POST /broadcasting/auth` объясняется
в разделе Realtime.

```
X-API-KEY: <ваш ключ>
```

## Отдельный контур, а не второй способ входа

Публичный контур (`/api/public/*`) и API веб-кабинета — разные поверхности с разной
аутентификацией. Bearer-токен кабинета здесь не работает; ключ, наоборот, не открывает
ручки кабинета. Заголовок называется ровно `X-API-KEY` — ни `Authorization`, ни `Api-Key`
не распознаются, и оба дают тот же ответ, что и полное отсутствие ключа.

### 401 — 401 — ключ не принят

| Что произошло | Что делать |
| --- | --- |
| Запрос отклонён до всякой бизнес-логики: ни одного действия не выполнено, ничего не списано. Тело одинаковое у всех эндпоинтов: `{"success": false, "message": "API key is missing. Provide it in the X-API-KEY header.", "data": null}`. Анонимных запросов публичный контур не принимает нигде. | Убедиться, что заголовок называется ровно `X-API-KEY` (не `Authorization`, не `Api-Key`) и значение передано целиком. Если ключ верный — открыть раздел разработчика и проверить, что ключ активен и срок не вышел. Повторять запрос бессмысленно: 401 детерминирован, ретрай с тем же ключом даст тот же ответ. |

`Retry-After`: нет. Разбор: https://lumean.app/developers/docs/errors/401

Ключ хешируется (sha256) и резолвится с кэшем около часа. Практическое следствие: правка
прав или деактивация ключа в кабинете применяется не мгновенно — запросы могут ещё
какое-то время идти по старому состоянию.

## Одиннадцать прав и wildcard

Право проверяется до бизнес-логики: ключ без нужного права получает `403` и ничего
не выполняет. Колонка «операций» — сколько ручек публичного API открывает право
(страницы справочника плюс `POST /broadcasting/auth`).

| Право | Что открывает | Операций |
| --- | --- | --- |
| `orders.read` | Чтение заказов и чанков, превью разбиения текста, WebSocket-подписка на заказы | 9 |
| `orders.write` | Создание, отмена и повтор заказов; повтор и перегенерация чанков | 6 |
| `orders.download` | `POST /storage/url` — обмен пути файла на временную ссылку | 1 |
| `templates.read` | Чтение шаблонов, `browse`, `config-options` | 4 |
| `templates.write` | Создание, изменение и удаление шаблонов | 3 |
| `voices.read` | Все каталоги голосов: LumVoice, ElevenLabs, HeyGen, Cartesia, Fish Audio; свои клоны и их квота | 14 |
| `voices.write` | Создание, повтор и архивирование клонов голоса Cartesia и Fish Audio | 6 |
| `billing.read` | `usage`, `subscriptions` | 3 |
| `profile.read` | `GET /user` | 1 |
| `reseller.read` | Кабинет реселлера: профиль и баланс, настройки, статистика, коды с полным значением | 5 |
| `reseller.write` | Выпуск подарочных кодов с баланса реселлера и их отмена | 2 |
| `*` | Проходит любую проверку прав, включая права, которых ещё не существует, — **кроме** `reseller.read` и `reseller.write` | все, кроме реселлера |

Две операции каталога AI-моделей (`GET /ai/models` и `GET /ai/models/{key}`) права
не требуют вовсе — в таблице их нет.

> [!WARNING]
> Права реселлера `*` **не покрывает** и ни в один пресет они не входят: подарочный код —
> деньги на предъявителя, поэтому ключ получает `reseller.read` и `reseller.write` только
> явным перечислением. Ключ с wildcard на `GET /reseller` ответит `403`.

> [!WARNING]
> `orders.download` **не покрывается** `orders.read`. Ключ, который прекрасно читает заказы
> и видит пути в `result.files[]`, на обмене пути на ссылку получит 403. Это самая частая
> причина неожиданного отказа в конце сценария — когда файл уже сгенерирован и оплачен.

### POST /storage/url

Get File URL

Справочник: https://lumean.app/developers/docs/api/post-storage-url

## Три пресета

При создании ключа права обычно набираются пресетом.

| Пресет | Права | Не открывает |
| --- | --- | --- |
| `read_only` | `orders.read`, `orders.download`, `templates.read`, `voices.read`, `billing.read`, `profile.read` | всё, что пишет заказы, шаблоны и клоны голоса, и кабинет реселлера |
| `automation` | то же плюс `orders.write` | `POST`, `PUT`/`PATCH` и `DELETE /templates/{template}`, создание, повтор и архив клонов, кабинет реселлера |
| `full` | все права, кроме реселлерских (в том числе `templates.write` и `voices.write`) | кабинет реселлера |

Wildcard `*` — отдельное значение, а не синоним пресета `full`: он проходит и те проверки,
которых на момент выдачи ключа не существовало (но не права реселлера). Какой из двух
способов «дать всё» применяет кабинет при выборе `full`, источники не уточняют — если это
важно, сверьтесь со списком прав уже созданного ключа в кабинете.

### Ловушка automation

Пресет с названием «для автоматизации» **не содержит `templates.write`** — только
`templates.read`. Это не опечатка в документации и не баг: так он и устроен. По той же
логике в нём нет и `voices.write`: ключу, который клонирует голоса, это право добавляют
вручную либо берут `full`.

Последствие конкретное. Для TTS голос задаётся не полем заказа, а `config.tts_settings.voice_id`
шаблона — значит канонический сценарий начинается с `POST /templates`. На ключе `automation`
он останавливается на первом же шаге: 403, заказ так и не создан.

**Правильно**

Для сценария «создать шаблон → заказать TTS» брать пресет `full` — либо `automation`
и вручную добавить `templates.write` при создании ключа.

**Неправильно**

Взять `automation`, потому что задача называется автоматизацией, и потом искать причину
403 в самом заказе — хотя отказал шаг создания шаблона.

Если шаблон создан заранее (в вебе или другим ключом), `automation` достаточно: владелец
шаблона — аккаунт, а не конкретный ключ. Чужой шаблон при этом не откроется никаким ключом.

### 403 · `template_access_denied` — template_access_denied — нет доступа к шаблону

| Что произошло | Что делать |
| --- | --- |
| Доменный отказ создания заказа: HTTP 403, тело `{"success": false, "message": "…", "reason": "template_access_denied"}`. Заказ не создан. | Проверить, что шаблон виден ключу. Владелец шаблона — аккаунт, а не конкретный ключ: шаблон, созданный в вебе, годится для API и наоборот, а вот чужой шаблон не откроется никаким ключом. Если шаблон свой — дело в правах: `automation` не включает `templates.write`, но `templates.read` в нём есть. |

`Retry-After`: нет. Разбор: https://lumean.app/developers/docs/errors/template-access-denied

## Заголовки языка и таймзоны

Оба заголовка необязательны и ни один из них не объявлен параметром в OpenAPI —
сгенерированный по спеке клиент про них не узнает, отправлять придётся руками.

- `X-Locale` — язык человекочитаемых строк: `message` в ответах и названия в справочниках
  вроде `GET /voices/tags`. На машинные поля (`reason`, статусы, коды) не влияет никак,
  и ветвиться по `message` нельзя именно поэтому. Расхождение источников: OpenAPI называет
  этот заголовок в 79 описаниях и ни разу не упоминает `Accept-Language`, а справочник для
  LLM — наоборот; если язык ответа критичен, проверьте фактическое поведение на своём ключе
  и присылайте оба заголовка.
- `X-Timezone` — имя зоны IANA (`Europe/Moscow`). Моменты времени в ответах приходят
  в ISO-8601 с явным оффсетом, по умолчанию UTC. Голый оффсет (`+03:00`) отвергается:
  он не знает про переход на летнее время. Фактически применённую зону сервер возвращает
  тем же заголовком — прислав мусор, вы увидите в ответе `X-Timezone: UTC`.

## Что по ключу недоступно

Публичный контур не проводит платежей и не управляет собой. По ключу **нельзя**: пополнять
баланс, делать переводы, покупать подписки, менять профиль и управлять самими API-ключами.
Всё это остаётся в кабинете. Отдельно: у заказов нет `update`/`delete` — только `cancel`
и `retry`, а `PUT`/`PATCH`/`DELETE /orders/{order}` ответят 405/404.

## Смоук-тест ключа

Самая дешёвая проверка — профиль: одна операция, одно право, никаких побочных эффектов.

```bash
curl -s -o /dev/null -w '%{http_code}\n' \
  'https://api.lumean.app/api/public/user' \
  -H 'X-API-KEY: <ваш ключ>'
```

| Код | Что это значит |
| --- | --- |
| `200` | Ключ активен, право `profile.read` есть |
| `403` | Ключ **рабочий** — аутентификация прошла, нет только `profile.read` |
| `401` | Ключ не принят: не отправлен, обрезан, неизвестен, деактивирован или истёк |

Ключевой нюанс — вторая строка: `403` подтверждает, что ключ жив. Если `profile.read`
у вашего ключа нет по замыслу, проверяйте `GET /orders?per_page=1` — ей нужен только
`orders.read`.

### GET /user

Get profile of API key owner

Справочник: https://lumean.app/developers/docs/api/get-user

Ключи создаются в разделе [«Разработчикам»](/developers): там же видны действующие права
и лимиты конкретного ключа. Ключа ещё нет — сначала [регистрация](/register), ключи
выдаются только владельцу аккаунта.

---

- Эта же страница в браузере: https://lumean.app/developers/docs/guide/authentication
- Машинный справочник целиком: https://api.lumean.app/docs/llm.md
