---
title: "POST /orders/{order}/cancel — Отменить заказ"
url: https://lumean.app/developers/docs/api/post-orders-order-cancel
locale: ru
description: "Отменить заказ"
generated: 2026-11-08
operationId: order.cancel
method: POST
path: "/orders/{order}/cancel"
scopes: [orders.write]
spec_version: 1.0.0
---

# POST /orders/{order}/cancel

**Отменить заказ**

Отменяет заказ владельца ключа и возвращает заблокированные средства на баланс.

**Условия:**
- Заказ в статусе `created`, `pending` или `partially_completed`.

**Что возвращается.** У `created`/`pending` обработки не было — блокировка снимается
целиком. У `partially_completed` готовые фрагменты оплачиваются, а возвращается
только незавершённое: остаток блокировки — на баланс, неизрасходованные токены — в
квоту подписки. Заказ после отмены — `cancelled`.

Возврат токен-квоты ключа (если заказ создан по ключу) выполняется автоматически.

**Требуемое право ключа:** `orders.write`.

- Право ключа: `orders.write`

## Запрос

```bash
curl -X POST 'https://api.lumean.app/api/public/orders/{order}/cancel' \
  -H 'Accept: application/json' \
  -H 'X-API-KEY: YOUR_API_KEY'
```

## Параметры

| Поле | Где | Тип | Обяз. | Описание |
| --- | --- | --- | --- | --- |
| `order` | path | `string` | обяз. | UUID заказа — 36 символов вида `9f8b2c1a-4d3e-4f5a-8b9c-0d1e2f3a4b5c`, не число. Берётся из поля `id`: его возвращает `POST /orders` при создании и `GET /orders` в списке. Чужой заказ по вашему ключу не откроется — придёт `404`. |
| `X-Locale` | header | `string` | — | Язык локализованных текстов ответа (`message`, подписи, причины ошибок), код ISO-639-1. Необязателен; без него — язык аккаунта владельца ключа, затем `Accept-Language`, затем язык по умолчанию. Неизвестный или неподдерживаемый код пропускается так же, как отсутствующий. |
| `X-Timezone` | header | `string` | — | IANA-зона (`Europe/Moscow`), в которой ответ показывает моменты времени — ISO-8601 со смещением. Необязателен; без него даты приходят в UTC. Невалидная зона игнорируется. Применённую зону сервер возвращает в одноимённом заголовке ответа. |

## Тело запроса

Тела нет.

## Ответы

### 200 — Заказ отменён

**Поля ответа**

| Поле | Тип | Обяз. | Описание |
| --- | --- | --- | --- |
| `success` | `boolean` | обяз. | Признак успеха. Решение принимайте по HTTP-коду: у любого ответа 2xx здесь `true`, а ошибка приходит телом другой формы, где этого поля может не быть вовсе. |
| `message` | `string` | обяз. | Пояснение для человека, на языке аккаунта. Показать пользователю можно; разбирать программно — нет: формулировки меняются без предупреждения и кодом ошибки не являются. |
| `data` | `Order` | обяз. | Заказ после отмены: `status` = `cancelled`, зарезервированные средства и токен-квота уже возвращены. |
| `data.id` | `string` | обяз. | UUID заказа. Его подставляют в пути `/orders/{order}/…` и передают в `POST /orders/{order}/retry`. |
| `data.user_id` | `integer` | обяз. | ID владельца заказа. У заказов, созданных по API-ключу, это всегда владелец ключа — чужой заказ по ключу не увидеть. |
| `data.name` | `string` | обяз. | Название заказа: из него берутся имя скачиваемого файла и имя ZIP-архива. |
| `data.template` | `Template` | — | Шаблон, по которому создан заказ. Приходит только у заказов с `template_id`; у заказа без шаблона (`sfx`/`music` по `task_type`) поля нет. `config` внутри — настройки, с которыми выполняется ИМЕННО этот заказ: конфиг шаблона на момент создания заказа с наложенным `config_override`; правка шаблона после создания его не меняет. В списке `GET /orders` `config` приходит `null` — полный конфиг отдаёт `GET /orders/{order}`. Шаблон могли удалить после создания заказа: здесь он виден по-прежнему, но `GET /templates/{template}` ответит `404`, а новый заказ с этим `template_id` — `422`. У заказов, созданных до выхода этой версии API (конец сентября 2026 года), снимка нет: там `config` — текущий конфиг шаблона с наложенным `config_override`, и правка шаблона его меняет. |
| `data.template.id` | `string` | обяз. | UUID шаблона. Его кладут в `template_id` при создании заказа. |
| `data.template.user_id` | `integer` | обяз. | ID владельца шаблона. |
| `data.template.slug` | `string` | обяз. | Короткий публичный идентификатор для расшаривания. `null` у шаблона, которым не делились. |
| `data.template.name` | `string` | обяз. | Название шаблона — только для человека, на поведение генерации не влияет. |
| `data.template.service_key` | `string` | обяз. | Код сервиса, по схеме которого валидируется `config`: `elevenlabs`, `lumimg` и т. д. |
| `data.template.service` | `Service \| null` — nullable | обяз. | Сервис шаблона справочно: название и тарификация, без схем конфигурации. `null` означает, что сервиса с таким кодом больше нет. |
| `data.template.config` | `object` | обяз. | Настройки генерации: голос, модель, скорость и прочее — набор ключей задаёт сервис. Допустимые значения смотрите в `GET /templates/config-options?service=<код>`, значение вне схемы отклоняется с `422`. В заказе (`template` в `GET /orders/{order}`) это настройки самого заказа — снимок на момент его создания с `config_override`, а не текущий конфиг шаблона (у заказов, созданных до конца сентября 2026 года, — текущий конфиг шаблона с `config_override`). |
| `data.template.is_public` | `boolean` | обяз. | Опубликован ли шаблон в общем каталоге. |
| `data.template.folder_id` | `string` | обяз. | UUID папки, в которой лежит шаблон, либо `null` для корня. Структура папок видна в `GET /templates/browse`. |
| `data.template.created_at` | `string` — date-time — nullable | обяз. | Когда шаблон создан, ISO 8601. |
| `data.template.updated_at` | `string` — date-time — nullable | обяз. | Когда шаблон последний раз менялся, ISO 8601. |
| `data.template_id` | `string` | обяз. | UUID использованного шаблона либо `null`, если заказ создан без шаблона. |
| `data.task_type` | `TaskType` — `tts` · `image` · `txt2img` · `remix` · `image_edit` · `voice_clone` · `sfx` · `music` · `voice_search` · `cartesia_dub` · `elevenlabs_dub` | обяз. | Тип задачи — он определяет, что лежит в `task_data` и что придёт в `result`. |
| `data.status` | `OrderStatus` — `created` · `pending` · `in_progress` · `completed` · `result_delivered` · `failed` · `compensated` · `cancelled` · `partially_completed` | обяз. | Текущее состояние заказа. Терминальных пять — `completed`, `result_delivered`, `failed`, `compensated`, `cancelled`; после них опрашивать заказ смысла нет. `partially_completed` — НЕ терминальный: часть чанков готова, часть упала. Файлы уже можно забирать, а сбойные фрагменты перезапускать через `POST /orders/{order}/items/retry-failed` — после повтора заказ может перейти в `completed`. `compensated` и `failed` — заказ закрыт без результата. `compensated` — штатный исход: ни один фрагмент не получился (сбой генерации или все фрагменты отклонены контентной политикой), блокировка по заказу снята, квота возвращена; удерживается только плата за попытки `policy_flagged` (см. `items[].status`). `failed` — редкий: заказ упал на подготовке входных файлов (возврат при этом сделан сразу) либо автоматический возврат не прошёл — такой заказ доводит поддержка. Если хоть один фрагмент готов, сбой даёт не их, а `partially_completed`: готовое оплачивается, упавшее можно повторить. |
| `data.price_units` | `integer` | обяз. | Заблокированная под заказ сумма в минимальных единицах LMC. Показывать это число как есть нельзя: реальное значение — `price_units / 10^precision`, где `precision` берётся из актива рядом. Готовое к показу значение лежит в соседнем decimal-поле. |
| `data.price_formatted` | `number` — nullable | обяз. | Та же сумма, что и `price_units`, но в целых LMC — готова к показу. `null`, пока стоимость не зафиксирована. |
| `data.currency_asset` | `Asset` | обяз. | Актив суммы — всегда LMC. Его `precision` нужен, чтобы перевести минимальные единицы в реальное значение. |
| `data.currency_asset.id` | `integer` | обяз. | Внутренний идентификатор актива. |
| `data.currency_asset.code` | `string` | обяз. | Код актива: `LUMC` — внутренняя валюта, `TOKEN` — токены генерации. |
| `data.currency_asset.kind` | `AssetKind` — `money` · `unit` | обяз. | Вид актива: деньги или расходуемые единицы. От него зависит, где сумма считается платежом, а где — расходом квоты. |
| `data.currency_asset.precision` | `integer` | обяз. | Число десятичных знаков. **Ключевое поле:** любая целая сумма этого актива делится на `10^precision`, чтобы получить реальное значение. Не считайте, что делитель равен 100. |
| `data.currency_asset.name` | `string` | обяз. | Название актива для показа, на языке аккаунта. |
| `data.currency_asset.deleted_at` | `string` — date-time — nullable | обяз. | Когда актив выведен из обращения, ISO 8601. `null` у действующего. |
| `data.currency_asset.created_at` | `string` — date-time — nullable | обяз. | Когда актив заведён, ISO 8601. |
| `data.currency_asset.updated_at` | `string` — date-time — nullable | обяз. | Когда актив последний раз менялся, ISO 8601. |
| `data.total_tokens` | `integer` — nullable | обяз. | Полная стоимость заказа в токенах: исходные чанки плюс все повторы и перегенерации. Это единица квоты, а не деньги. |
| `data.total_duration_ms` | `integer` — nullable | обяз. | Суммарная длительность полученного аудио в миллисекундах. Это длина результата, а не время, потраченное на генерацию. |
| `data.task_data` | `object` — nullable | обяз. | Входные данные задачи ровно в том виде, в каком их принял сервер: текст, ссылки на загруженные файлы, применённые настройки. Набор ключей зависит от `task_type`. |
| `data.result` | `object` — nullable | обяз. | Результат выполнения. `files[]` — основные файлы; `service_files[]` — вспомогательные (субтитры `.srt`/`.vtt`/`.lrc`, alignment) у TTS-заказов. Пути **абсолютные** и готовы к передаче в `POST /storage/url`. `null`, пока заказ не завершён, а также у упавшего заказа: подробностей ошибки в публичном контуре нет. |
| `data.created_at` | `string` — date-time — nullable | обяз. | Когда заказ создан, ISO 8601. |
| `data.updated_at` | `string` — date-time — nullable | обяз. | Когда заказ последний раз менялся, ISO 8601. Растёт на каждом переходе статуса — годится как дешёвый признак «что-то произошло». |
| `data.files_expire_at` | `string` — nullable | обяз. | Срок хранения файлов заказа. `files_expire_at` — момент удаления (`null`, если заказ ещё не завершён или файлы уже удалены); `files_expired` — файлов больше нет, скачивать нечего. |
| `data.files_expired` | `boolean` | обяз. | `true` — срок хранения истёк и файлы уже удалены: ссылку на них получить нельзя, заказ нужно создавать заново. |
| `data.retention` | `object` | обяз. | Сроки хранения по уровням файлов. Пофрагментные дорожки склеенного заказа удаляются раньше самого результата. |
| `data.retention.chunks` | `object` | обяз. | Срок жизни пофрагментных дорожек — ими работают правка пауз, пересборка финала и перегенерация отдельного фрагмента. |
| `data.retention.chunks.expires_at` | `string` | обяз. | Когда исчезнут пофрагментные дорожки, ISO 8601. До этого момента доступны правка пауз, пересборка и перегенерация отдельного фрагмента. `null` — заказ ещё не завершён (отсчёт не начат) либо фрагментов уже нет. |
| `data.retention.chunks.expired` | `boolean` | обяз. | `true` — пофрагментных дорожек больше нет: правка и пересборка отклоняются. Готовый результат при этом может быть ещё доступен — смотрите `retention.files`. |
| `data.retention.chunks.expires_early` | `boolean` | обяз. | `true` — фрагменты исчезнут раньше результата (заказ склеен в отдельный файл). `false` — фрагменты и есть результат, оба уровня истекают одновременно. |
| `data.retention.chunks.reason` | `string` — `chunks_purged` · `storage_expired` · `null` — nullable | обяз. | Почему фрагменты недоступны: `chunks_purged` — удалены по своему сроку, результат ещё на месте; `storage_expired` — удалены все файлы заказа. `null` — фрагменты доступны. |
| `data.retention.files` | `object` | обяз. | Срок жизни всех файлов заказа, включая результат. Дублирует поля `files_expire_at` / `files_expired` верхнего уровня. |
| `data.retention.files.expires_at` | `string` — nullable | обяз. | Когда будут удалены все файлы заказа, ISO 8601. То же значение, что в `files_expire_at` — поле верхнего уровня сохранено для совместимости. |
| `data.retention.files.expired` | `boolean` | обяз. | То же, что `files_expired`: файлов больше нет, скачивать нечего. |
| `data.eta_seconds` | `integer` — nullable | обяз. | Оценка оставшегося времени, в секундах — только пока заказ выполняется. У завершённого и у ещё не начатого `null`. |
| `data.eta_at` | `string` — date-time — nullable | обяз. | Ожидаемый момент готовности, ISO 8601 — тот же прогноз, что и `eta_seconds`, только абсолютным временем. |
| `data.completed_chunks` | `integer` — nullable | обяз. | Сколько исходных чанков уже готово. Повторы и перегенерации сюда не входят — иначе прогресс уезжал бы выше 100 %. |
| `data.total_chunks` | `integer` — nullable | обяз. | Сколько исходных чанков в заказе всего. Ноль означает, что разбиение ещё не выполнено. |
| `data.progress_percent` | `integer` — nullable | обяз. | Готовность в процентах, 0–100 — производная от `completed_chunks` и `total_chunks`, считать самому не нужно. |
| `data.stitching` | `boolean` | обяз. | `true` — идёт склейка аудио: результат ещё не финальный. Бывает и при `status = completed` — после перегенерации фрагмента финал пересобирается, и до конца склейки `result` указывает на прежнюю дорожку. Скачивать итог — когда `stitching = false`. |
| `data.paragraphs` | `array<object>` — nullable | обяз. | Сводка по абзацам: индекс, число фрагментов, общий статус, прогресс и аудиофайл (`result_file`) каждого абзаца. `null` — заказ создан в обычном режиме, ориентируйтесь на `items[]`. Чтобы абзацы появились, создавайте заказ с `config_override.generation_mode = paragraph` (подробности — в описании этого поля). |
| `data.paragraphs[].paragraph_index` | `integer` | обяз. | Номер абзаца, с нуля. |
| `data.paragraphs[].chunks_count` | `integer \| number` | обяз. | Сколько чанков попало в этот абзац. |
| `data.paragraphs[].completed_chunks` | `string \| integer` | обяз. | Сколько чанков абзаца уже готово. |
| `data.paragraphs[].status` | `string` | обяз. | Сводный статус абзаца: он выводится из статусов его чанков, а не хранится отдельно. Словарь свой, короче общего: `pending`, `in_progress`, `failed`, `completed` — заблокированный модерацией чанк тоже даёт `failed`. Считаются только исходные чанки, поэтому успешный повтор упавшего фрагмента статус абзаца НЕ меняет: смотрите на сам фрагмент в `items[]`. |
| `data.paragraphs[].progress_percent` | `integer` | обяз. | Готовность абзаца в процентах, 0–100. |
| `data.paragraphs[].result_file` | `string` — nullable | обяз. | Склеенное аудио абзаца целиком: абсолютный путь либо структура с путём и размером. Скачивается через `POST /storage/url`, как и остальные файлы заказа. `null` читается по-разному в зависимости от `chunks_count`: при `chunks_count = 1` собственного файла у абзаца нет и не будет — абзац это и есть тот единственный фрагмент, берите его `result_file` из `items[]` по тому же `paragraph_index`; при `chunks_count > 1` склейки ещё не было — многочанковый абзац получает файл ТОЛЬКО после неё, никогда заранее. |
| `data.items` | `array<OrderItem>` | — | Чанки заказа. Приходят в детальном ответе `GET /orders/{order}`; в списке `GET /orders` поля нет — за ними идите в `GET /orders/{order}/items`. |
| `data.items[].id` | `string` | обяз. | UUID чанка. Подставляется в пути `/orders/{order}/items/{item}/…`. |
| `data.items[].order_id` | `string` | обяз. | UUID заказа, которому принадлежит чанк. |
| `data.items[].item_type` | `string` | обяз. | Природа записи: `chunk` — исходный фрагмент, `retry` — бесплатный повтор упавшего фрагмента, `regeneration` — платная переделка готового. Повторы и перегенерации живут отдельными записями с тем же `chunk_index`: история попыток сохраняется целиком, а звучит в результате последняя. |
| `data.items[].chunk_index` | `integer` — nullable | обяз. | Порядковый номер фрагмента в заказе, с нуля. Задаёт порядок склейки итогового файла. |
| `data.items[].paragraph_index` | `string` | обяз. | Номер абзаца, к которому относится фрагмент, — заполняется только у исходных фрагментов абзацного заказа. `null` и в обычном режиме, и у записей повтора либо перегенерации: у них своей привязки к абзацу нет, её берут у родительского фрагмента через `parent_item_id`. Режим включается ключом `generation_mode` в `config_override` заказа. |
| `data.items[].parent_item_id` | `string` | обяз. | UUID исходного чанка — у записей `retry` и `regeneration`. У самого исходного чанка `null`. |
| `data.items[].original_text_length` | `integer` | обяз. | Длина текста, с которой фрагмент создавался. Служит потолком для `text` в `regenerate`. |
| `data.items[].current_text_length` | `integer` | обяз. | Длина актуального текста фрагмента: после перегенерации отличается от `original_text_length`. |
| `data.items[].price_units` | `integer` | обяз. | Стоимость фрагмента в **токенах** — это не деньги. Денежная сумма лежит у самого заказа, в его поле `price_units` (там LMC, здесь токены; поля называются одинаково, единицы разные). |
| `data.items[].consumed_units` | `integer` | обяз. | Сколько токенов фактически списано по этому фрагменту. У незавершённого фрагмента — 0. |
| `data.items[].remaining_locked` | `integer` | обяз. | Сколько токенов ещё зарезервировано под фрагмент. Обнуляется, когда фрагмент завершается или отменяется. |
| `data.items[].status` | `string` | обяз. | Состояние фрагмента: `pending` — ждёт воркера, `processing` — в работе, `completed` — готов, `failed` — техническая ошибка, `policy_flagged` — отклонён контентной политикой. Разница между двумя последними определяет способ лечения: `failed` чинится повтором как есть, `policy_flagged` — только переформулировкой текста, повтор с прежним будет отклонён снова. Попытка `policy_flagged` у ElevenLabs не бесплатна: она расходует ресурс провайдера и без результата, поэтому из суммы, которая вернулась бы за фрагмент, удерживается фиксированная плата за попытку (на заказах из квоты — эквивалент в токенах). Удерживается только из возвращаемого — сверх заблокированного по заказу не списывается ничего, баланс в минус не уходит. Денежная часть видна в истории операций как `policy_block_fee`; из квоты просто возвращается меньше токенов. |
| `data.items[].result_file` | `object \| string \| null` — nullable | обяз. | Файл готового фрагмента: абсолютный путь либо структура с путём и размером. Скачивается через `POST /storage/url`, как и файлы заказа. `null`, пока фрагмент не готов. |
| `data.items[].duration_ms` | `integer` — nullable | обяз. | Длительность полученного аудио в миллисекундах — длина записи, а не время генерации. У не-аудио задач `null`. |
| `data.items[].attempt_number` | `integer` | обяз. | Номер попытки для этого фрагмента, начиная с 1. Растёт с каждым повтором. |
| `data.items[].can_retry` | `boolean` | обяз. | Разрешён ли бесплатный повтор прямо сейчас. Учитывает статус, тип задачи и исчерпание попыток — проверять условия самому не нужно. |
| `data.items[].can_regenerate` | `boolean` | обяз. | Разрешена ли платная перегенерация прямо сейчас. Доступна только для завершённых фрагментов. |
| `data.items[].created_at` | `string` — date-time — nullable | обяз. | Когда фрагмент создан, ISO 8601. |
| `data.items[].updated_at` | `string` — date-time — nullable | обяз. | Когда фрагмент последний раз менялся, ISO 8601. |
| `data.items[].failure_reason` | `string` — nullable | — | Причина падения фрагмента для показа пользователю — локализованный текст на языке запроса, не машинный код (ветвиться по нему нельзя, формулировки меняются). Есть только у `failed` и `policy_flagged`; остальным, а также когда причину определить не удалось, приходит `null`. |
| `data.tokens_from_quota` | `integer` — nullable | — | Сколько из потраченных токенов покрыла квота подписки. `null` — из квоты не покрыто ничего. |
| `data.tokens_from_payg` | `integer` — nullable | — | Сколько токенов оплачено сверх квоты, из баланса LMC. `null` — доплаты не было. |
| `data.tokens_spent` | `integer` — nullable | — | Итог по двум предыдущим полям: сколько токенов списано за заказ (квота + доплата). Заказ, покрытый безлимитом подписки, и бесплатные версии сюда не входят — у безлимитного заказа поле `null`; объём генерации — `total_tokens`. Повторы (`retry`) не входят — они не тарифицируются заново. |
| `data.queue_position` | `integer` — nullable | — | Место заказа в очереди: сколько заказов стоит впереди, `0` — следующий. Поле есть у любого типа задачи, пока заказ ждёт свободного исполнителя (у `voice_search` — пока не готова проверка); когда работа началась, поля нет. Отсутствие ключа — «не в очереди», а не «позиция неизвестна». |
| `data.queue_wait_seconds` | `integer` — nullable | — | Оценка ожидания в очереди, в секундах. Считается только для поиска голоса; у остальных задач и пока нет статистики — `null`. Оценка, а не обещание: пересчитывается на каждый ответ. |

**Пример**

```json
{
  "success": true,
  "message": "Order cancelled successfully.",
  "data": {
    "id": "e6f7a8b9-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
    "user_id": 501,
    "template_id": "7e2a4c1d-8b3f-4a5e-9c6d-1f2e3a4b5c6d",
    "task_type": "tts",
    "status": "cancelled",
    "price_units": 300,
    "total_tokens": 0,
    "task_data": {
      "text": "A shorter narration cancelled before processing started.",
      "total_length": 300
    },
    "result": null,
    "created_at": "2026-07-17T13:00:00+00:00",
    "updated_at": "2026-07-17T13:05:00+00:00",
    "eta_seconds": null,
    "eta_at": null,
    "completed_chunks": 0,
    "total_chunks": 2,
    "progress_percent": 0
  }
}
```

### 400 — Невозможно отменить заказ в текущем статусе: reason=invalid_order_status

**Поля ответа**

| Поле | Тип | Обяз. | Описание |
| --- | --- | --- | --- |
| `success` | `boolean` | обяз. | Всегда `false` у ошибок. |
| `message` | `string` | обяз. | Причина отказа словами, на языке аккаунта. Для показа пользователю; ветвиться по ней нельзя — формулировки меняются. |
| `errors` | `null` — nullable | обяз. | Разбор по полям — только у ошибок валидации (`422`): ключ соответствует полю запроса, значение — список претензий к нему. У остальных кодов приходит `null`: разбирать нечего, причина целиком в `message`. |

**Пример**

```json
{
  "success": false,
  "message": "An order with the current status cannot be cancelled.",
  "reason": "invalid_order_status",
  "error_code": "invalid_order_status"
}
```

### 401 — Невалидный или отсутствующий X-API-KEY

**Поля ответа**

| Поле | Тип | Обяз. | Описание |
| --- | --- | --- | --- |
| `success` | `boolean` | обяз. | Всегда `false` в ответах об ошибке. |
| `message` | `string` | обяз. | Текст ошибки на языке ключа (задаётся заголовком `X-Locale`). |
| `data` | `null` — nullable | обяз. | Всегда `null`, когда запрос отклонён до обработки. |

**Пример**

```json
{
  "success": false,
  "message": "API key is missing. Provide it in the X-API-KEY header.",
  "data": null
}
```

### 403 — Нет доступа к заказу или у ключа нет права orders.write

**Поля ответа**

| Поле | Тип | Обяз. | Описание |
| --- | --- | --- | --- |
| `message` | `string` | обяз. | Error overview. |

**Пример**

```json
{
  "success": false,
  "message": "This API key does not have permission to perform this action."
}
```

### 404 — Заказ не найден

**Поля ответа**

| Поле | Тип | Обяз. | Описание |
| --- | --- | --- | --- |
| `success` | `boolean` | обяз. | Всегда `false` в ответах об ошибке. |
| `message` | `string` | обяз. | Текст ошибки на языке ключа (задаётся заголовком `X-Locale`). |
| `reason` | `string` | — | Машиночитаемая причина — приходит у бизнес-отказов (например, `invalid_order_status`); у прочих ошибок поля нет. Ветвите обработку по нему, а не по тексту сообщения. |
| `error_code` | `string` | — | Тот же машинный код, что в `reason`, — второе имя поля. Приходит вместе с `reason`, значения всегда совпадают. |

**Пример**

```json
{
  "success": false,
  "message": "Resource not found."
}
```

---

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