Перейти к содержанию

Реестр кодов ошибок

Каждая ошибка API возвращается в формате RFC 7807 (application/problem+json) с обязательным стабильным полем code (snake_case) и идентификатором трассировки traceId. Поле code — часть контракта /v1, по нему вызывающая сторона надёжно ветвит логику. Переименование или удаление кода — ломающее изменение: оно помечается BREAKING и перечисляется в разделе «Существенные изменения контракта» справочника API. Некоторые ошибки несут в теле дополнительные поля с подробностями (например, conflictingTagId у конфликта тега) — они отмечены в столбце «Когда».

{
  "type": "about:blank",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "Currency of source account must match the requested currency",
  "code": "currency_mismatch",
  "traceId": "0af1c2d3e4f5a6b7c8d9e0f1a2b3c4d5"
}

Как обрабатывать ошибки

Ветвите логику по стабильному code, а не по тексту detail (он человекочитаемый и может меняться). Ответы 4xx (валидация, «не найдено», конфликт состояния) повторять не следует; 5xx, 503 и сетевые сбои безопасно ретраить с backoff — изменяющие баланс операции идемпотентны по заголовку Idempotency-Key. Ответ 429 несёт заголовок Retry-After и поле retryAfterSeconds — по ним видно, когда повторять.

Идемпотентность и версия записи

code HTTP Когда
idempotency_key_reused 422 Заголовок Idempotency-Key уже занят ДРУГОЙ операцией: повтор с тем же ключом на другой ручке или с другим телом запроса.
version_conflict 409 Запись изменена другим пользователем: версия из If-Match устарела — тег, метка, черновик конфигурации программы, реестр условий акции, версия настройки карточки клиента. Тот же код — у слияния клиента, уже слитого в другого клиента.
version_required 428 Изменение версионируемой записи (тег, метка, черновик конфигурации программы, реестр условий акции, версия настройки карточки клиента) пришло без заголовка If-Match или значение в нём не разобрать.

Счета и списание баллов

code HTTP Когда
account_not_found 404 Счёт по номеру или идентификатору не найден.
not_enough_funds 402 Недостаточно баланса/доступного остатка (с учётом резервов) для списания, перевода или обмена. Доп. поля: accountNumber, amount, currency.
points_account_not_found 404 У клиента нет счёта в валюте баллов (начисление, списание, hold).
hold_not_found 404 Резерв (hold) по идентификатору не найден у клиента.
redemption_limit_not_found 404 Лимит списания по разрезу (уровень/валюта/сегмент) не найден при удалении.
currency_mismatch 422 Валюта счёта не совпадает с валютой запроса (пополнение, обмен).
account_number_blank 422 Номер счёта пуст.
redemption_below_min 422 Сумма списания меньше минимально допустимой по политике, лимиту или правилам списания активной конфигурации программы.
redemption_above_max 422 Сумма списания больше максимально допустимой по политике, лимиту или правилам списания активной конфигурации программы.
redemption_below_min_balance 422 Доступный баланс клиента меньше минимального баланса для списания из правил активной конфигурации программы.
redemption_not_multiple 422 Сумма списания не кратна шагу из правил списания конфигурации программы.
redemption_scope_not_eligible 422 Покупка не подходит под область списания конфигурации: сумма чека меньше минимальной либо в чеке нет позиций, на которые можно тратить баллы.
redemption_items_required 422 Область списания «товары» или «категории», а в запросе hold/redemptions нет позиций чека items.
redemption_purchase_amount_required 422 Область списания «от минимальной суммы», а сумма чека purchaseAmountMinor не передана.
hold_not_active 409 Резерв уже зафиксирован (commit), отменён (cancel) или истёк — повторная операция над ним невозможна.
points_expiry_in_progress 409 Ручной запуск сгорания баллов (POST /v1/maintenance/points/expire) вызван, пока уже идёт другой прогон (advisory-блокировка занята).
points_expiry_notice_in_progress 409 Ручной запуск прогона предупреждений о сгорании (POST /v1/maintenance/points/expiry-notice) вызван, пока уже идёт другой прогон.
invalid_bound_type 422 Тип границы лимита списания не FIX/PERCENT.
invalid_scope_type 422 Тип разреза лимита списания не TIER/CURRENCY/SEGMENT.
negative_value 422 Значение (процент кэшбэка, граница лимита) отрицательное.

Леджер

code HTTP Когда
ledger_account_dual_balance 422 Перевод на/со счёт с одновременно дебетовым и кредитовым остатком — тип счёта не однозначен для проводки.
chart_of_account_invalid 422 Статья плана счетов в проводке не разбирается (внутренняя ошибка настройки плана счетов).
ledger_reference_duplicate 409 Проводка с такой бизнес-ссылкой (reference) уже есть — резервная защита от дублей поверх идемпотентности леджера: повтор логической операции под новым ключом идемпотентности.

Достижения

code HTTP Когда
achievement_not_found 404 Правило достижения по идентификатору не найдено (карточка, изменение, удаление).
achievement_code_taken 409 Код достижения уже занят другим правилом.
achievement_condition_invalid 422 Условие правила не согласовано: нет порога у порогового условия или нет кода уровня у условия «достигнут уровень».

Мобильный кошелёк

code HTTP Когда
wallet_disabled 404 Выпуск карты в Apple Wallet/Google Кошелёк выключен настройкой loyalty.wallet.enabled.
wallet_card_not_active 409 Карта участника не в статусе ACTIVE (клиент заблокирован) — паспорт в кошелёк не выпускается.

Валюты и обмен

code HTTP Когда
exchange_rate_not_found 404 Нет курса обмена для пары валют source→target.
currency_code_blank 422 Код валюты пуст.
currency_code_required 422 Код валюты не передан при изменении старого справочника /v1/admin/point-currencies.
negative_rate 422 Курс балльной валюты отрицательный.
currency_not_found 404 Валюта по коду не найдена (в операциях и в GET /v1/currencies/{code}).
point_currency_not_found 404 Валюта баллов не найдена в старом справочнике /v1/admin/point-currencies.
exchange_rate_source_currency_mismatch 422 Сумма курса обмена задана не в исходной валюте пары.
exchange_rate_target_currency_mismatch 422 Целевая валюта курса не совпадает с исходной.
same_currency_exchange 422 Валюты счёта-источника и счёта-получателя обмена совпадают (так же — у пары обмена и запроса базового курса).
same_account_exchange 422 Обмен между одним и тем же счётом.
non_positive_amount 422 Сумма обмена не положительна.
account_type_invalid 422 Тип счёта (системный/клиентский) не подходит операции обмена (например, источник должен быть клиентским, а получатель — системным).
accounts_owner_mismatch 422 Счёт-источник и счёт-получатель обмена должны принадлежать одному клиенту.
exchange_currency_not_configured 422 Для валюты не настроен клиринговый (deposit/funding) счёт обмена.

Справочник валют

code HTTP Когда
currency_code_invalid 422 Денежная валюта не входит во встроенный перечень ISO, либо код балльной валюты не по формату (латиница A–Z, цифры, _, 2–16 символов).
currency_code_reserved 422 Код балльной валюты совпадает с зарезервированным кодом денежной валюты ISO.
currency_code_taken 409 Код валюты уже занят другой записью справочника.
currency_precision_invalid 422 Точность отображения вне диапазона 0–максимум.
currency_rate_required 422 У балльной валюты не задан обязательный курс.
currency_rate_currency_invalid 422 Валюта курса не найдена среди включённых денежных валют, либо курс валюты бюджета акций указан не в базовой валюте.
rate_scale_exceeded 422 В курсе больше допустимого числа знаков после запятой.
money_currency_required 422 Нет ни одной включённой денежной валюты, чтобы выразить курс балльной валюты или базовую валюту.
currency_in_use_by_rate 409 Денежную валюту нельзя выключить: её курс используют включённые балльные валюты. Доп. поле: currencies.
base_currency_required 422 Базовая денежная валюта должна быть включена; снять признак базовой можно, только назначив базовой другую валюту; базовую валюту нельзя выключить.
currency_has_operations 409 Символ и точность валюты не меняются: по ней уже есть операции.
currency_in_use 409 Валюту нельзя удалить: есть ссылки — счета с проводками или системные счета (ACCOUNTS), субсчета (SUBACCOUNTS), курсы (RATES), лимиты списания (REDEMPTION_LIMITS), системные настройки и курсы обмена (SYSTEM_SETTINGS), пары обмена (EXCHANGE_PAIRS). Счёт клиента без операций ссылкой не считается и удаляется вместе с валютой. Доп. поле: references.
currency_enabled 409 Удалить можно только выключенную валюту.
currency_disabled 422 Начисление в выключенную валюту отклоняется (списание и сторно остатка проходят).
currency_zero_rate 422 Курс валюты баллов равен нулю — бюджет акции в деньгах не пересчитать; обнулить курс валюты бюджета нельзя, пока есть открытые акции с бюджетом. Доп. поле: promotions.
base_currency_used_by_budget 409 Смена базовой валюты, пока акции расходуют бюджет в деньгах прежней базовой. Доп. поле: promotions.

Пары обмена валют

code HTTP Когда
exchange_pair_not_found 404 Пара обмена по идентификатору не найдена.
exchange_pair_exists 409 Направление обмена уже занято парой — своей или парой «в обе стороны» с обратной стороны.
exchange_pair_enabled 409 Удалить можно только отключённую пару.
exchange_pair_currency_invalid 422 В паре не балльная валюта: обмен возможен только между балльными валютами.
exchange_pair_currency_immutable 422 Валюты пары после создания не меняются.
exchange_pair_currency_disabled 422 Пару нельзя включить: одна из её валют выключена.
exchange_rate_invalid 422 Курс пары не больше нуля или в нём больше допустимого числа знаков до или после запятой.
exchange_rate_undefined 422 Базовый курс направления не определён: курс валюты не задан, равен нулю или выражен не в базовой валюте.
exchange_pack_invalid 422 Размер пачки в режиме курса «пачками» — не целое число от 1.
exchange_minimum_not_multiple 422 Минимум обмена по направлению не кратен размеру пачки.
exchange_subaccount_invalid 422 Субсчёт в ограничениях направления не подходит: нужен активный или закрытый субсчёт валюты направления.

Клиенты

code HTTP Когда
customer_not_found 404 Клиент по externalId не найден.
customer_already_exists 409 Клиент с таким externalId уже существует.
invalid_customer_status 422 Нераспознанный статус клиента при разборе данных.
invalid_phone 422 Телефон не приводится к канонической форме.
invalid_email 422 Email не проходит проверку формата.
customer_timezone_invalid 422 Часовой пояс в профиле клиента (PUT /v1/customers/{externalId}/profile, поле timezone) — не идентификатор IANA.
merge_same_customer 422 Попытка слить клиента с самим собой.
merge_account_conflict 422 Операции в одной и той же валюте были и у выжившего клиента, и у источника слияния — нужен ручной перенос остатка через леджер. Счета без операций слиянию не мешают.
bulk_size_exceeded 400 Массовая операция превышает предел размера и отклоняется до обработки элементов: массовые действия каталога клиентов и JSON-пакеты ручных операций — loyalty.manual-operations.bulk-max-ids; присвоение и снятие тегов, пакетное удаление тегов и меток, проставление и снятие меток акций (в том числе список меток в bulk-label-assign/bulk-label-remove), проверка списков значений, набор тегов пакета ручной операции — max-bulk-targets/max-batch-ids/max-lookup-values справочников тегов и меток; пакетное удаление полей и версий настройки карточки клиента — loyalty.client-profile.max-bulk-ids.

Ручные операции с баллами и пакеты

code HTTP Когда
insufficient_points 422 Доступный остаток субсчёта меньше суммы корректировки/начисления в ручной операции или строке пакета (отдельно от платёжного not_enough_funds).
unknown_reason_code 422 Код причины операции отсутствует в справочнике «Причины операций» или запись не активна.
operation_batch_not_found 404 Пакет ручной операции по batchId не найден.
reason_comment_required 400 Причина «Прочее» указана без обязательного комментария.
already_processed 409 Строка пакета уже проведена под тем же reference (повтор списка под новым ключом идемпотентности).
batch_schedule_in_past 422 Момент отложенного выполнения пакета уже прошёл.
batch_schedule_too_far 422 Момент отложенного выполнения дальше горизонта loyalty.manual-operations.scheduler.max-ahead.
batch_scheduling_disabled 422 Планировщик отложенных пакетов выключен на контуре — отложенный пакет никогда бы не выполнился.
customer_blocked 422 Заблокированному клиенту запрещены ручные операции с баллами и уровнем (начисление, списание, перевод уровня) — для одиночной операции и для строки пакета. Добавление и снятие тегов заблокированному клиенту доступно.
batch_already_running 409 У оператора уже есть активный пакет (queued/running) — второй пакет не принимается. Доп. поле: batchId активного пакета.
batch_transport_unavailable 503 Брокер сообщений недоступен при публикации чанков пакета — пакет не создан, повтор возможен тем же ключом идемпотентности.

Несогласованные параметры операции или пакета (нет суммы, причины, ссылки; у операций с тегами — лишние сумма, причина, субсчёт или время выполнения) отклоняются общим кодом 400 validation_failed (см. «Технические коды»).

Коды строк пакета

В errors[] массовых операций и в CSV-отчёте пакета код строки показывает этап отказа. Отказ проверкой списка — тот же код, что в отчёте проверки (customer_not_found, customer_blocked, insufficient_points и т. п.). Отказ уже при выполнении — тот же код с префиксом execution_ (execution_insufficient_points, execution_unknown_tag — тег удалён или слит после приёма пакета). Строка, до которой пакет не дошёл из-за системного сбоя, — batch_aborted. Теги пакета проверяются один раз, на приёме: тега нет в справочнике — отказ всему запросу 422 unknown_tag, а не строкам.

Теги клиента

code HTTP Когда
tag_not_found 404 Тег по идентификатору не найден.
tag_already_exists 409 Тег с таким значением уже есть в справочнике. Доп. поля: conflictingTagId, value.
tag_value_invalid 422 Значение тега не проходит нормализацию/валидацию.
tag_merge_into_itself 422 Попытка слить тег сам с собой.
tag_bundle_invalid 422 Загруженный файл бандла тегов не прочитан или не проходит проверку формата.
unknown_tag 422 Присвоение по значению/идентификатору тега, которого нет в справочнике (создание клиента, присвоение тегов, импорт, пакет ручной операции «Добавить теги»/«Снять теги»). Доп. поля: unknownTags/unknownTagIds.
tag_in_use 409 Тег стоит в условии аудитории работающей акции — удаление сломало бы отбор клиентов.

Метки акций

code HTTP Когда
label_not_found 404 Метка по идентификатору не найдена. Доп. поле: missingLabelIds.
label_already_exists 409 Метка с таким значением уже есть в справочнике. Доп. поля: conflictingLabelId, value.
label_value_invalid 422 Значение метки не проходит нормализацию/валидацию.
unknown_label 422 Присвоение метки, которой нет в справочнике, при создании акции или проставлении меток. Доп. поля: unknownLabels/unknownLabelIds.
label_merge_into_itself 422 Попытка слить метку саму с собой.
label_bundle_invalid 422 Загруженный файл бандла меток не прочитан или не проходит проверку формата.
label_in_use 409 Метка стоит в условии аудитории работающей акции — удаление сломало бы отбор.

Условия аудитории акции

code HTTP Когда
promotion_audience_invalid 422 Условия аудитории акции не проходят проверку (несуществующая ссылка, значение в обеих зонах include/exclude и т. п.). Доп. поле: errors.
promotion_audience_unresolved 400 Запуск акции с условием, ссылающимся на удалённый тег, метку, акцию или сегмент клиентов: сохранить черновик можно, запустить — нельзя. Доп. поле: unresolved/errors; у сегмента в errors[] — kind: SEGMENT, код сегмента в value, id: null.
promotion_in_use 409 На линию версий акции ссылается условие аудитории работающей акции — последнюю версию линии не удалить.

Механики и акции

code HTTP Когда
promotion_not_found 404 Акция по идентификатору не найдена.
mechanic_not_found 404 Механика (шаблон акции) по коду не найдена в справочнике механик.
mechanic_not_found_in_promotion 404 Механика, указанная в акции, не найдена (создание/изменение акции).
mechanic_in_use 409 Механику нельзя удалить: на неё ссылаются акции.
mechanic_no_lifecycle 409 У механик нет статусов жизненного цикла в справочнике — операция смены статуса неприменима.
unknown_mechanic_code 422 Код механики не входит в закрытый список веток расчёта (зарезервированный код, в текущей реализации не достигается — справочные механики принимаются по строковому коду).
mechanic_code_blank 422 Код механики пуст.
mechanic_code_invalid 422 Код механики не по формату (латиница/цифры/_, начинается с буквы).
mechanic_title_blank 422 Название механики пусто.
mechanic_type_blank 422 Тип механики пуст.
mechanic_diagram_blank 422 Имя диаграммы RT Flow пусто (механика = диаграмма RT Flow).
mechanic_diagram_invalid 422 Имя диаграммы RT Flow не по формату.
mechanic_param_invalid 422 Параметр механики в файле переноса негоден: пустой ключ или название, ключ повторяется, тип не из списка. Появляется только в отчёте импорта механик (POST /v1/admin/mechanics/import), текстом причины — наружу кодом ответа не уходит.
promotion_priority_required 400 Акция без приоритета в импортируемом бандле (обычные POST/PUT без приоритета отклоняются раньше, общей ошибкой валидации 400 validation_failed — приоритет обязателен с 26.3.0, значение по умолчанию сервер больше не подставляет).
promotion_not_revisable 409 Новую версию (revise) можно создать только из ACTIVE/PAUSED; DRAFT правится напрямую, COMPLETED — копией, ARCHIVED — сначала разархивировать.
promotion_status_invalid 409 Недопустимый переход статуса акции (например, активировать можно не из любого статуса).
promotion_mechanic_not_configured 409 Запуск (в том числе массовый) акции на механике, у которой не заведены параметры: награду задать негде. Запланированные и работающие акции не останавливаются.
promotion_not_editable 409 Правка на месте запрещена: акция активна, завершена, в архиве или на паузе с хотя бы одним применением — нужна новая версия (завершённую — копией, архивную — сначала вернуть из архива). То же — у PUT/DELETE /v1/promotions/{id}/participation-limit.
promotion_not_deletable 409 Удалить безвозвратно можно только акцию в статусе DRAFT/SCHEDULED.
promotion_name_taken 409 Имя акции уже используется другой линией версий (регистронезависимо).
promotion_concurrent_update 409 Массовая операция над акцией столкнулась с конкурентной правкой цели (optimistic lock) — попадает в errors[], не рвёт запрос.
promotion_period_invalid 422 ends_at должен быть позже starts_at.
promotion_param_required 422 Обязательный параметр механики не передан — в том числе награда «Множителя», «Подарка» и «Начисления за единицу» (multiplier, giftMinor, pointsPerUnit).
promotion_param_type 422 Параметр механики должен быть числом.
promotion_param_min 422 Значение параметра механики меньше минимума.
promotion_param_max 422 Значение параметра механики больше максимума.
participation_limit_not_found 404 Лимит участий для акции не задан (GET/DELETE /v1/promotions/{id}/participation-limit).
invalid_period 422 Период лимита участий не входит в DAY|WEEK|MONTH|TOTAL (год не принимается), либо начало периода позже конца (журнал аудита, отчёты /v1/reports/**, выдачи мониторинга), либо ширина окна мониторинга days не положительна.
invalid_participation_window 422 Окно лимита участий не согласовано: не указан период; не указана длительность или режим для периода не «за всё время»; календарный период задан из нескольких единиц; «за последние N» — не в днях или короче 2 дней.
invalid_max_count 422 Максимальное число участий не больше нуля.
invalid_budget 422 Бюджет акции не больше нуля.
invalid_max_bonus 422 Максимальная сумма бонуса не больше нуля.
invalid_total_limit 422 Общий лимит участий не больше нуля.
promotion_labels_not_accepted 400 Поле меток передано в форме создания/правки акции — метки правятся только пакетными операциями bulk-label-assign/bulk-label-remove.
promotion_event_type_invalid 422 Тип события акции eventType — не код опубликованной записи справочника «Типы событий» (значение, уже сохранённое в акции, при правке принимается).
promotion_points_settings_not_applicable 422 Срок жизни баллов, тип начисляемых баллов или область списания заданы у акции на механике, которая баллы не начисляет.
promotion_points_subaccount_invalid 422 Тип начисляемых баллов акции (pointsSubaccountCode) — субсчёт, которого нет в валюте баллов программы или который не принимает начисления; проверяется и перед запуском.
promotion_redemption_scope_invalid 422 Область списания баллов акции (pointsRedemptionScope): пустое или повторённое значение либо больше 1000 значений.

Условия акции (criteria)

При отказе в теле — criterion (код условия), mode (зона) и, где применимо, values (значения, на которых остановилась проверка).

code HTTP Когда
promotion_criterion_unknown 422 Условие не поддерживается, задано без режима либо скрыто или удалено в «Настройке акции» и получает новые значения.
promotion_criterion_value_kind_mismatch 422 Вид значения не совпадает с условием: перечень вместо диапазона и наоборот, у условия нет выбранного способа method, несколько значений там, где разрешено одно.
promotion_criterion_values_empty 422 У условия нет значений или есть пустое значение; у диапазона не задана ни одна граница.
promotion_criterion_value_invalid 422 Значение или граница диапазона добавленного условия не разбирается по типу способа: число — с точкой, дата — ISO 8601.
promotion_criterion_range_invalid 422 Границы диапазона неверны: нижняя больше верхней, граница суммы чека отрицательна.
promotion_criterion_duplicate 422 Условие в одном режиме задано дважды.
promotion_criterion_zones_overlap 422 Одни и те же значения (или пересекающиеся диапазоны) выбраны в зонах «применяется» и «не применяется».
promotion_criterion_value_not_found 422 Новых значений нет среди опубликованных записей справочника условия (ранее сохранённые принимаются в любом статусе).

Реестр условий акции

Отказы сохранения реестра условий на экране «Настройка акции» (PUT /v1/admin/promotion-criteria). Условие, на котором остановилась проверка, — в теле criterion {code, label} (кроме criterion_key_invalid).

code HTTP Когда
criterion_box_immutable 422 Правка или удаление коробочного условия: у него меняются только показ и порядок.
criterion_key_invalid 422 Переменная покупки не латиницей, цифрами, «_» или «-» либо длиннее 64 символов; поля профиля клиента нет или оно в архиве.
criterion_key_duplicate 422 Переменная покупки или поле профиля уже используется в другом условии (без учёта регистра); в criterion — условие, которое заняло её раньше.
criterion_method_invalid 422 Способы задать значение у добавленного условия не согласованы: способов нет, вид повторяется, справочник неизвестен, тип значения недопустим, способ не подходит полю профиля.
criterion_locked_after_use 422 Условие уже заполнено в акциях: источник и переменная не меняются, использованная зона не снимается, использованный способ не снимается и не меняется.
criterion_in_use 409 Удаляемые условия заполнены в акциях со статусом «Активна», «Пауза» или «Запланирована». Доп. поля: criteria — все такие условия [{code, label}], promotions — акции, которые их держат.
profile_field_used_in_criterion 409 Поле профиля клиента нельзя удалить: на нём построено условие акции. Доп. поле: criteria [{code, label}] (в пакетном удалении — в строке errors[]).

Согласование запуска акции

Действия POST /v1/promotions/{id}/approvals/{submit|approve|reject|cancel} и запуск акции при включённом согласовании.

code HTTP Когда
approval_forbidden 403 approve/reject без права согласующего LOYALTY_PROMOTION_APPROVE.
approval_not_assigned 403 Пользователь не входит в поимённый список согласующих этой отправки.
approval_self_forbidden 409 Решение по своей же отправке: согласует другой человек.
approval_status_invalid 409 Действие не из допустимого статуса согласования, включая повтор уже выполненного.
approval_disabled 409 Согласование выключено настройкой контура — действия согласования недоступны.
approval_required 409 Запуск несогласованной акции при включённом согласовании (в bulk-activate — строкой errors[]).

Партнёры и партнёрские предложения

code HTTP Когда
partner_not_found 404 Партнёр по идентификатору не найден.
partner_offer_not_found 404 Партнёрский оффер по идентификатору не найден.
partner_unknown 422 Партнёра с кодом partnerCode из транзакции у партнёра нет в реестре.
partner_in_use 409 Партнёра нельзя удалить: у него есть офферы, мерчанты или проводки по счёту финансирования.
partner_unresolved 422 Транзакцию не удалось сопоставить с партнёром ни по partnerCode, ни по mid (мерчант справочника, отнесённый к партнёру), ни по mcc (только если MCC однозначно указывает на одного партнёра).
partner_name_blank 422 Название партнёра пусто.
partner_code_blank 422 Код партнёра пуст.
partner_code_invalid 422 Код партнёра не по формату (латиница/цифры/_/-, начинается с буквы или цифры).
partner_code_duplicate 409 Код партнёра уже занят.
partner_status_invalid 422 Статус партнёра не ACTIVE/BLOCKED.
partner_offer_not_draft 409 Править можно только оффер-черновик — приостановите оффер перед правкой.
partner_offer_transition 409 Недопустимый переход статуса оффера.
partner_offer_active 409 Активный оффер удалять нельзя — приостановите/архивируйте.
partner_offer_in_use 409 По офферу есть атрибуции (обороты, вознаграждения) — удаление запрещено, оффер архивируется.
partner_offer_not_active 409 Оффер недоступен для активации клиентом (не в статусе ACTIVE).
partner_offer_auto 409 Безакцептный оффер (AUTO) активировать акцептом не нужно.
partner_offer_out_of_period 409 Оффер вне периода действия.
partner_offer_not_eligible 409 Оффер недоступен для этого клиента по аудитории.
partner_offer_title_blank 422 Название оффера пусто.
partner_offer_delivery_required 422 Способ доставки (PROMOCODE/CALCULATED) не указан.
partner_offer_acceptance_required 422 Модель акцепта (OPT_IN/AUTO) не указана.
partner_offer_value_required 422 Тип и значение вознаграждения не указаны.
partner_offer_period_invalid 422 Период действия оффера некорректен (начало не раньше конца).
partner_offer_promocode_required 422 Для промокод-оффера не указан код или кампания Promo.
partner_offer_mechanic_required 422 Для транзакционного (CALCULATED) оффера не указана механика (диаграмма RT Flow).
partner_offer_segments_required 422 Для сегментной аудитории не указаны сегменты.
partner_offer_segment_not_found 422 Новый код сегмента в аудитории оффера отсутствует в справочнике сегментов.

Мерчанты

code HTTP Когда
merchant_not_found 404 Мерчант по коду (MID) не найден.
merchant_code_duplicate 409 MID уже занят — сравнение точное, с учётом регистра.
merchant_partner_unknown 422 Партнёр мерчанта (partnerCode) отсутствует в реестре партнёров.
merchant_city_unknown 422 Город мерчанта (cityCode) отсутствует в справочнике городов.

Справочники географии

code HTTP Когда
city_not_found 404 Город по коду не найден.
city_code_duplicate 409 Код города уже занят — сравнение точное, с учётом регистра.
city_region_unknown 422 Регион города (regionCode) отсутствует в справочнике регионов geo-region.
city_timezone_invalid 422 Часовой пояс города — не идентификатор IANA.
city_has_stores 422 Город нельзя архивировать: к нему привязаны действующие торговые точки.
store_not_found 404 Торговая точка по коду не найдена.
store_code_duplicate 409 Код точки уже занят — сравнение точное, с учётом регистра.
store_city_unknown 422 Город точки (cityCode) отсутствует в справочнике городов.

Каталог товаров

code HTTP Когда
product_category_not_found 404 Категория товаров по коду не найдена.
product_category_code_duplicate 409 Код категории уже занят.
product_category_level_invalid 422 Категория первого уровня задана с родителем либо второго-третьего уровня — без родителя.
product_category_parent_unknown 422 Родитель категории (parentCode) отсутствует в справочнике категорий.
product_category_cycle 422 Родитель не на уровень выше дочерней категории — цикл или пропуск уровня.
product_category_has_children 422 Категорию нельзя удалить: у неё есть дочерние категории.
product_category_has_items 422 Категорию нельзя удалить: она проставлена у товаров.
product_item_not_found 404 Товар по коду не найден.
product_item_code_duplicate 409 Код товара уже занят.

Удаление категории или товара, на которые ссылаются условия акций, отклоняется 409 dictionary_entry_in_use.

Сегменты клиентов

code HTTP Когда
segment_not_found 404 Сегмент по коду не найден (в том числе удалён пользователем во время заливки — нужна новая регистрация).
segment_already_exists 409 Регистрация существующего сегмента без перезаливки (replace): дополнения состава нет, состав приходит целиком.
segment_fill_stale 409 Момент расчёта заливки раньше уже применённой: устаревший расчёт не заменяет свежий состав.
segment_fill_not_open 409 Пачка участников или завершение пришли в заливку, которая уже не открыта.
segment_batch_too_large 413 В пачке участников больше объектов, чем loyalty.segments.max-members-per-request.
segment_in_use 409 Сегмент нельзя удалить: он в условиях запланированной, активной или приостановленной акции. Доп. поле: promotions.

Справочники и НСИ

code HTTP Когда
chart_of_account_not_found 404 Статья плана счетов по коду/идентификатору не найдена.
unit_not_found 404 Единица измерения по коду не найдена.
system_config_not_found 404 Параметр операционной конфигурации по ключу не найден.
program_timezone_invalid 422 Значение program.timezone (PUT /v1/admin/system-config/program.timezone) — не идентификатор IANA (например, Moscow или UTC+3).
dictionary_not_found 404 Справочник по ключу не найден в реестре.
dictionary_entry_not_found 404 Запись справочника по коду не найдена.
dictionary_entry_in_use 409 Запись справочника (в том числе категорию или товар каталога) нельзя удалить: на неё ссылаются акции — группой, типом события или значением условия в любой зоне. Число таких акций экран справочника показывает заранее (usedByPromotions).
dictionary_entry_archived 409 Архивная запись справочника не правится обычным сохранением — сначала восстановите её.
dictionary_code_blank 422 Код записи справочника пуст.
dictionary_label_blank 422 Название записи справочника пусто.
dictionary_status_transition 409 Недопустимый переход статуса записи справочника (DRAFT→ACTIVE→ARCHIVED).
dictionary_status_invalid 422 Запрошенный статус не входит в DRAFT/ACTIVE/ARCHIVED.
dictionary_read_only 409 Справочник только для просмотра через generic-API и перенос бандлом: внешний мастерится во внешней системе, локальный (валюты, системные счета, единицы) ведётся в своём разделе продукта.
dictionary_own_screen 409 Справочник ведётся на своём экране и своим API (теги клиента, метки акций, сегменты клиентов, города, торговые точки, мерчанты, категории товаров, товары) — generic-ручки /v1/admin/dictionaries/** его не открывают.

Схема и структура карточки клиента

code HTTP Когда
field_not_found 404 Поле схемы карточки клиента/уровня по идентификатору не найдено.
field_key_exists 409 Ключ поля уже используется другим полем этой версии настройки — в том числе архивным: такое поле возвращают из архива, а не заводят заново.
field_key_immutable 422 Ключ заведённого поля не меняется: под другой ключ заводится новое поле.
field_has_values 409 Поле заполнено у клиентов — его архивируют, а не удаляют (в пакетном удалении — строка errors[]).
system_field_immutable 422 Преднастроенное поле нельзя удалить или архивировать; значение преднастроенного поля или поля с колонкой источника не сохраняется через карточку клиента — оно приходит из системы.
invalid_field_type 422 Тип поля схемы вне закрытого списка. У карточки клиента — STRING/NUMBER/DATE/DATETIME/BOOLEAN: прежний LIST отклоняется, выпадающий список задаётся inputSource: DROPDOWN и refDict.
invalid_input_source 422 Способ ввода поля схемы вне закрытого списка; у карточки клиента — вне MANUAL/DROPDOWN/SYSTEM или SYSTEM у кастомного поля.
invalid_field_group 422 Расположение поля group не существует или это таблица, а не карточка.
field_order_invalid 422 Порядок полей схемы содержит повторы, неизвестный идентификатор или задан не для всех полей.
unknown_attribute 422 Значение пришло в поле, которого нет в схеме карточки (PUT /v1/customers/{externalId}/attributes).
field_archived 422 Значение пришло в архивное поле.
field_hidden 422 Значение пришло в поле, скрытое с карточки.
attribute_not_multiple 422 Больше одного значения у поля без множественного выбора.
group_not_found 404 Карточка или таблица по идентификатору не найдена.
section_not_found 404 Раздел таблиц по идентификатору не найден.
group_not_empty 409 Карточку нельзя удалить: в ней есть атрибуты, в том числе архивные.
section_not_empty 409 Раздел таблиц нельзя удалить: в нём есть таблицы.
system_group_immutable 422 Карточка или таблица поставляется с продуктом и не удаляется (переименовать и переставить можно).
system_section_immutable 422 Раздел таблиц поставляется с продуктом и не удаляется (переименовать и переставить можно).
invalid_group_type 422 Тип группы вне набора CARD/TABLE.
group_not_table 422 Столбцы или строки запрошены у карточки, а не у таблицы.
group_order_invalid 422 Порядок групп содержит повторы, неизвестный идентификатор или задан не для всех групп.
section_order_invalid 422 Порядок разделов содержит повторы, неизвестный идентификатор или задан не для всех разделов.
source_schema_not_allowed 422 Схема источника не входит в разрешённые (loyalty.client-profile.source-schemas).
source_table_not_found 422 Таблицы-источника нет или она недоступна приложению; у вкладки продукта строк нет.
source_link_not_found 422 У таблицы-источника нет строковой колонки external_id — строку не с чем связать с клиентом.

Версии настройки карточки клиента

code HTTP Когда
configuration_not_found 404 Версии настройки с таким идентификатором нет (в том числе уже удалённой).
configuration_active_immutable 409 Активную версию не правят: создайте копию, правьте её и сделайте активной (переименовать активную можно).
configuration_already_active 409 Версия уже активна.
configuration_field_has_values 409 В активируемой версии нет поля, которое заполнено у клиентов и показывается сейчас. Ключи полей — в detail.
configuration_active_undeletable 409 Активную версию удалить нельзя — одну или в составе выбора; при пакетном удалении не удаляется ничего.

Конфигурация программы и уровни

code HTTP Когда
config_not_found 404 Конфигурация программы по идентификатору не найдена.
config_name_duplicate 409 Название конфигурации уже занято.
config_already_active 409 Конфигурация уже активна.
config_active_readonly 422 Активная конфигурация не правится напрямую — дублируйте её, правьте копию и активируйте.
config_active_undeletable 422 Активную конфигурацию удалить нельзя; в массовом удалении отклоняется вся выборка.
config_has_customers 422 На черновике ещё живут клиенты (до своего пересмотра) — его нельзя ни править, ни удалить. Число таких клиентов заранее видно в поле customersCount.
config_base_tier_required 422 Активация конфигурации без уровня с порогом входа 0.
config_status_invalid 422 Статус конфигурации в базе вне набора — признак ручной правки данных.
tier_not_found 404 Уровень участия по коду не найден.
tier_code_duplicate 409 Код уровня повторяется в наборе уровней конфигурации.
tier_name_duplicate 409 Название уровня повторяется в наборе уровней конфигурации.
tier_threshold_required 422 У уровня не задан порог по оси, которую использует метрика перехода конфигурации.
tier_threshold_not_monotonic 422 Пороги уровней не возрастают строго (порог повторяется).
tier_base_threshold_required 422 В наборе нет уровня с порогом 0.
tier_base_undeletable 422 Прежний базовый уровень исключён из набора.
promotion_not_bindable 422 К программе привязывается завершённая или архивная акция либо уровню назначается неработающая акция.
promotion_not_in_program 422 В акциях уровня (tiers[].promotionIds) — акция, которой нет в акциях программы.
promotion_bound_to_config 422 Акцию нельзя удалить: её линия привязана к конфигурациям программы. Доп. поле: configs.
promotion_level_unknown 422 Условие «Уровень клиента» ссылается на несуществующую конфигурацию или уровень (в том числе при импорте акций между контурами).

Интеграции

code HTTP Когда
card_not_resolved 404 Карта лояльности на кассе не найдена или неактивна (GET /v1/integration/pos/cards/{cardId}).
resolve_rate_limited 429 Превышен лимит резолюций карты POS (правило rate-limit pos-card-resolve).
checkscan_customer_not_found 404 Клиент для проекции Check Scan не найден или неактивен.
checkscan_overview_rate_limited 429 Превышен лимит запросов проекции клиента Check Scan (правило checkscan-overview).
rtflow_source_invalid 422 Поле source начисления RT Flow не REFERRAL/RT_FLOW.
condition_check_invalid 400 Запрос проверки условий из RT Flow не разобрать: неизвестный type, пустой список значений, self в условии.
mdm_unavailable 503 Внешний реестр клиентов (MDM) недоступен (таймаут, обрыв, 5xx, протухший токен) — отличается от «клиента нет» (404).

Возврат по чеку

POST /v1/integration/pos/returns и POST /v1/integration/pos/returns/{returnId}/cancel.

code HTTP Когда
purchase_not_found 404 Покупки с таким номером чека нет либо она принадлежит другому клиенту.
return_amount_exceeds_purchase 422 Сумма возврата больше невозвращённого остатка покупки.
return_currency_mismatch 422 Валюта возврата не совпадает с валютой покупки.
return_not_found 404 Отмена неизвестного возврата.
return_already_cancelled 409 Возврат уже отменён.
return_id_conflict 409 Тот же returnId пришёл с другим телом запроса.

Исходящие уведомления

code HTTP Когда
notification_not_found 404 Сообщение очереди исходящих по идентификатору не найдено.
notification_not_parked 409 Повтор или снятие применены к сообщению, которое не в разборе.

Ограничение частоты (rate limiting)

code HTTP Когда
rate_limited 429 Общий код превышения лимита для правил без специального кода (значение задаётся конфигурацией loyalty.rate-limit.rules[].code).
integration_rate_limited 429 Превышен лимит интеграционного периметра /v1/integration/** (чтение или запись, правила integration-read/integration-write).
event_rate_limited 429 Превышен лимит событий покупок POST /v1/events/purchase (правило events).
bulk_rate_limited 429 Превышен лимит массовых операций (импорт/пакеты/bulk-начисления/сгорание, правило bulk).
b2c_rate_limited 429 Превышен лимит запросов клиентского кабинета /v1/b2c/** (правило b2c).

Импорт файлов

code HTTP Когда
import_file_empty 422 Загруженный файл или текстовый список пуст.
import_file_binary 415 Ожидается текстовый CSV, получен архив/исполняемый/иной бинарный формат по сигнатуре.
import_bad_encoding 422 Файл не в кодировке UTF-8 (например, UTF-16).
import_too_many_rows 422 В файле/списке больше строк, чем разрешено за один импорт/пакет. Доп. поле: maxRows.
import_file_infected 422 Файл отклонён антивирусной проверкой.
import_file_unreadable 422 Не удалось прочитать содержимое загруженного файла.
import_file_too_large 413 Файл больше допустимого размера загрузки.
import_no_rows 422 В файле импорта (клиенты, категории и товары каталога) только заголовок, строк с данными нет.
import_missing_columns 422 В заголовке файла импорта (клиенты, категории и товары каталога) нет обязательных колонок. Доп. поле: columns.
import_no_contact_column 422 В строгом режиме импорта клиентов нет ни одной контактной колонки (phone/email).

Коды строк отчёта импорта

Отчёт проверки и загрузки CSV (клиенты, категории и товары каталога) называет проблему строки своим кодом — это не HTTP-ответ, а строка отчёта: import_duplicate_in_file — идентификатор или код повторяется в файле, import_external_id_required — не заполнен external_id клиента, import_code_required — не заполнен код категории или артикул товара, import_name_required — нет фамилии или имени клиента либо названия новой категории или товара, import_contact_required — у клиента нет ни телефона, ни email, import_field_too_long — значение длиннее допустимого, import_status_invalid — статус категории или товара не ACTIVE/ARCHIVED, import_row_failed — строка прошла проверку, но запись не удалась. Отказы с кодом из реестра (например, invalid_phone, customer_already_exists) приходят тем же кодом.

Обмен данными

code HTTP Когда
exchange_job_not_found 404 Задание регламентного обмена по коду не найдено.
exchange_job_running 409 Ручной запуск задания обмена, пока предыдущий прогон ещё выполняется.
exchange_cron_invalid 422 Расписание задания обмена не разбирается как cron-выражение.
exchange_cursor_invalid 422 Курсор ленты изменений не распознан — нужно начать выборку заново, задав changedSince.
exchange_field_unknown 422 В потоке переливки DTP нет колонки, объявленной в конфигурации соответствия полей.
dtp_process_not_configured 409 Для витрины DTP-переливки нет описания процесса или запроса переливки.

Субсчета баллов

code HTTP Когда
subaccount_not_found 404 Субсчёт по идентификатору или коду в валюте не найден.
subaccount_code_duplicate 409 Код субсчёта уже занят в этой валюте.
subaccount_not_active 409 Субсчёт в состоянии, не принимающем начисления (не активен), — при начислении, в том числе строкой пакета ручной операции.
subaccount_base_cannot_close 409 Базовый субсчёт закрывается только вместе с валютой.
subaccount_used_by_promotions 409 Субсчёт нельзя закрыть: в него начисляют незавершённые акции (выбран как тип начисляемых баллов). Доп. поле: promotions.
subaccount_immutable_after_use 422 Валюта или правило сгорания субсчёта не меняются: по нему уже есть проводки.
subaccount_base_expiry_fixed 422 Базовому субсчёту задан режим сгорания, отличный от NONE: своего срока у него нет, баллы живут по общему сроку.
subaccount_base_restrictions_fixed 422 Базовому субсчёту заданы ограничения списания — у него их нет.
subaccount_restriction_invalid 422 Ограничение списания субсчёта (товар, категория, мерчант, торговая точка) пустое или повторяется.
subaccount_expiry_in_past 422 Фиксированный момент сгорания expiryAt раньше текущего — при создании, правке правила или активации черновика.
subaccount_expiry_passed 422 Начисление на субсчёт, фиксированный момент сгорания которого уже наступил.
subaccount_expiry_invalid 422 Период сгорания субсчёта не разбирается (ожидается ISO-8601 в днях/часах) или не согласован с режимом сгорания, либо не положителен.
subaccount_priority_taken 422 Порядок очереди списания субсчетов валюты содержит повторы или задан не для всех субсчетов валюты.
subaccount_currency_mismatch 422 Валюта субсчёта не совпадает с валютой операции (зарезервированный код; в текущей реализации проверка валюты субсчёта выполняется через subaccount_not_found).
subaccount_period_invalid 422 Начало периода отчёта по субсчёту (GET .../totals) позже конца.

Приём команд

code HTTP Когда
intake_payload_invalid 422 Тело команды очереди приёма не проходит проверку конкретного поля.
intake_command_not_found 404 Команда очереди приёма по идентификатору события не найдена.
intake_command_not_parked 409 Операция разбора (повтор, отмена) применяется к команде не в статусе PARKED.
intake_discard_reason_required 422 Отмена отложенной команды без обязательного основания (зарезервирован — через REST недостижим: пустое основание отклоняется раньше валидацией запроса, 400 validation_failed).
intake_schedule_too_far 422 Срок исполнения команды дальше горизонта хранения очереди приёма.
intake_command_not_scheduled 409 Отмена команды, назначенной на будущее, когда её срок уже наступил (в работе у обработчика) или она не в состоянии ожидания.

B2C — личный кабинет клиента

code HTTP Когда
b2c_unauthenticated 422 Запрос к клиентскому контуру пришёл совсем без токена.
b2c_subject_missing 422 В клиентском токене нет идентификатора участника программы лояльности (claim субъекта).

Реферальная программа

code HTTP Когда
invalid_referral_link_status 422 Нераспознанный статус реферальной связи при разборе данных.
referral_sort_invalid 400 Поле сортировки списка приглашённых клиентов не поддерживается.
referral_status_invalid 400 Значение фильтра по статусу реферальной связи не поддерживается.
referral_code_generation_failed 500 Не удалось сгенерировать уникальный реферальный код клиента после максимального числа попыток.

Технические коды

Универсальные коды уровня фреймворка — единый обработчик ошибок Spring MVC достраивает code и traceId даже там, где тело ошибки собрано не доменным кодом (валидация полей, нечитаемое тело, несуществующий маршрут).

code HTTP Когда
validation_failed 400 Нарушены правила полей тела или параметров (обязательность, длина, диапазон, формат) либо параметры операции не согласованы между собой. detail перечисляет нарушения поле: сообщение через ; по алфавиту, путь вложенного поля — criteria[0].mode.
bad_request 400 Тело или значение параметра не удалось разобрать (нечитаемый JSON, promotionId=abc).
access_denied 403 Субъекту не хватает требуемой роли LOYALTY_*: отказ проверки прав на ручке (@PreAuthorize) или в сервисе, где право зависит от тела запроса (операция пакета ручных операций, причина «Прочее», отправка и отмена согласования акции, изменение акций уровней в конфигурации программы).
not_found 404 Нет маршрута/обработчика для запроса.
method_not_allowed 405 Метод не поддерживается для ресурса.
not_acceptable 406 Невозможно удовлетворить заголовок Accept.
unsupported_media_type 415 Неподдерживаемый Content-Type.
request_error 4xx Прочие клиентские ошибки без специального кода.
internal_error 500 Непредвиденная ошибка. Стектрейс логируется с traceId, наружу не отдаётся.

Рассогласование данных, которое может возникнуть только при правке базы в обход приложения, отдаётся как 500 со стабильным кодом — по нему и traceId сопровождение находит причину:

code HTTP Когда
lot_expiry_inconsistent 500 Срок партии баллов не согласован с его источником (в том числе при списании).
return_accrual_missing 500 При отмене возврата не найдено начисление исходной покупки.
profile_active_configuration_missing 500 Нет ни одной активной версии настройки карточки клиента.
profile_configuration_status_unknown 500 Статус версии настройки карточки в базе вне набора ACTIVE/DRAFT.
profile_group_type_unknown 500 Тип группы карточки в базе вне набора CARD/TABLE.