---
title: "Соглашения"
url: https://lumean.app/developers/docs/guide/conventions
locale: ru
description: "Формат ответов и ошибок, базовый URL, типы идентификаторов и формат дат."
updated: 2026-10-18
sources: [get-orders, post-orders, get-orders-chunks-preview-preview-id, get-voices-elevenlabs-library]
errors: ["422", "404"]
spec_version: 1.0.0
---

# Соглашения

Формат ответа, адреса, идентификаторы и время одинаковы во всех операциях API.

## Конверт ответа

```json
{ "success": true,  "message": "<текст для человека>", "data": <payload> }
{ "success": false, "message": "<причина>" }
```

Успешные ответы (200 и 201) и большинство отказов приходят в этом конверте. У ошибок `data` нет
или равно `null`. Отказы `401` и `403` при проверке ключа и прав присылают `data: null` явно.
Поле `errors` бывает только у `422`.

Доменные отказы добавляют к конверту машинные поля. Почти всегда это `reason`, и то же значение
приходит в `error_code`. У токен-квоты добавляются `window`, `limit`, `used`, `reset_at` и
`retry_after`. В режиме явного подтверждения доплаты `402` и `409` несут поля котировки:
`shortfall_tokens`, `quote_token`, `expires_at`, `actual_lmc_minor`, `quoted_lmc_minor`.

## Ошибки валидации (422)

```json
{
  "success": false,
  "message": "<общее сообщение>",
  "errors": { "config.tts_settings.voice_id": ["текст ошибки", "..."] }
}
```

Ошибка в полях запроса приходит в том же конверте, с полем `errors`. Ключи `errors` — пути полей
запроса через точку, а не имена верхнего уровня.

### 422 — 422 — запрос не принят

| Что произошло | Что делать |
| --- | --- |
| Запрос не принят, ничего не создано. Ошибка в полях приходит в общем конверте: `{"success": false, "message": "…", "errors": {"field": ["…"]}}`. | Сначала проверьте, есть ли в теле `errors`. Если есть, исправьте перечисленные поля. Если `errors` нет, а есть `reason`, поля запроса ни при чём: то же тело вернёт тот же отказ. Откройте страницу этого кода. |

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

Если в ответе `422` есть `errors`, исправьте поля запроса. Если `errors` нет, а есть `reason`
(`content_blocked`, `text_empty`, `service_not_found` и другие), поля в порядке, а запрос отклонён
по содержанию. Тот же запрос снова вернёт тот же ответ.

## Базовый URL и окружение

| Что | Значение |
| --- | --- |
| REST base | `https://api.lumean.app/api/public` |
| WebSocket | `wss://ws.lumean.app:443`, app key `7c4dd881d8116ac76fe89aff71d8c2ff` |
| WS auth | `POST https://api.lumean.app/api/public/broadcasting/auth` |
| OpenAPI | `https://api.lumean.app/docs/public-openapi.json` (EN: `…/public-openapi.en.json`) |
| AsyncAPI | `https://api.lumean.app/docs/public-asyncapi.json` |

Окружение одно: песочницы и тестового хоста у публичного API нет. Тестовые запросы идут на тот же
адрес и оплачиваются так же. Проверить запрос без списаний можно бесплатным превью разбиения
`POST /orders/chunks/preview`.

Все запросы идут по HTTPS. Тело запроса — JSON (`Content-Type: application/json`), кроме загрузки
файлов (`multipart/form-data`). Ответы — JSON в UTF-8.

## Типы идентификаторов

| Ресурс | Тип | Вид |
| --- | --- | --- |
| Order, Template | UUID (строка) | `8f14e45f-ceea-467a-9c0e-4d2b9f1b2c3d` |
| User, ApiKey, Subscription, Service | integer | `42` |
| Внешний голос (ElevenLabs, HeyGen) | строковый `voice_id` провайдера | формат задаёт провайдер |
| Превью чанков (`previewId`) | sha256, 64 hex-символа, без дефисов | `3f9a1c…` |

UUID — только у заказов и шаблонов, поэтому проверять любой id как UUID нельзя.

`preview_id` — не идентификатор ресурса, а хеш содержимого. Он зависит от текста, шаблона и
режима: тот же текст даёт тот же `preview_id`, и ответ приходит из кэша сразу. Кэш общий для
владельца, поэтому он сработает и для текста, который уже считала веб-сессия того же аккаунта.
Нового `preview_id` на повторный запрос не будет.

`voice_id` внешнего провайдера передаётся не в заказе, а в шаблоне, в
`config.tts_settings.voice_id`. Подробнее — в руководстве [Шаблоны](/developers/docs/guide/templates).

Для WebSocket нужен числовой `id` пользователя из `GET /user`, а не UUID заказа: приватный канал
называется `private-orders.{userId}`. Подробнее — в руководстве [Realtime](/developers/docs/guide/realtime).

### GET /orders/chunks/preview/{previewId}

Страница предпросмотра

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

## Даты и время

```
2026-07-08T12:34:56+00:00
```

Время в ответах приходит в ISO-8601 с явным смещением, по умолчанию в UTC. Заголовок
`X-Timezone` с именем зоны IANA переводит время в вашу зону: см.
[Ключ, права и заголовки](/developers/docs/guide/authentication). Календарные даты в формате
`Y-m-d`, например границы периодов действия, в другую зону не переводятся: зоны у них нет.

## Пагинация

```json
{ "items": [...], "current_page": 1, "last_page": 5, "per_page": 20, "total": 93 }
```

Обычные списки возвращают такой объект в `data`. Счётчики лежат рядом с `items`, параметры
запроса — `page` (с единицы) и `per_page`. Каталоги голосов ElevenLabs и HeyGen отдают другую
обёртку, `{ voices, total, page, page_size, has_more }`, и считают `page` с нуля. Подробнее — в
руководстве [Пагинация](/developers/docs/guide/pagination).

## Как читать ошибки

Разбирайте ответ в таком порядке:

1. HTTP-код — класс ответа.
2. `reason` в теле — машинный код отказа. Ветвиться нужно по нему.
3. `errors` — только у `422` с ошибкой в полях запроса: словарь «путь поля → массив сообщений».
4. `message` — текст для человека на языке ответа. Формулировки меняются без предупреждения и
   зависят от `X-Locale`, поэтому по `message` код ошибки не определяют.

Все коды `reason` разобраны в [каталоге ошибок](/developers/docs/errors). Там же есть
[диагност](/developers/docs/errors#s-diagnose): вставьте в него тело ответа целиком.

---

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