# 12K Loyalty API — полная публичная документация

> Этот файл генерируется из фактической FastAPI-схемы. Внутренние методы кабинета и platform-admin намеренно исключены.

Базовый URL: `https://api.landlancer.online`

Публичных HTTP-операций: **139**, из них BonusPlus-compatible: **40** — 39 из индексированного каталога + `PUT /retail/giftCard`.

Машинная схема: [`/docs/openapi.json`](https://landlancer.online/docs/openapi.json).

## Важный статус совместимости

Все 39 публичных путей из индексированного каталога BonusPlus существуют; отдельно документированный `PUT /retail/giftCard` также реализован, всего 40 compatibility-операций. `READY` означает покрытую основную семантику; `PARTIAL` — рабочий путь, у которого ещё не воспроизведены отдельные закрытые поля, CRM/RFM-фильтры или неизвестные внутренние правила BonusPlus. Транспортный паритет не является заявлением о полном production-паритете без дифференциального теста на реальном аккаунте BonusPlus и физическом ЭВОТОР.

Официальный каталог для сверки: <https://bonusplus.pro/api/Help>.

## Versioning and deprecation

Все versioned native `/v1`, `/public/v1` и BonusPlus-compatible `/compat/bonusplus` операции управляются проверяемым file-backed registry. Текущий production registry содержит только `active` операции: deprecated и sunset endpoints сейчас отсутствуют.

Когда операция действительно переводится в `deprecated`, OpenAPI получает `deprecated: true`, replacement и даты, а runtime отвечает стандартными `Deprecation`, `Sunset` и `Link`. Удаление или narrowing контракта CI разрешает только после новой major-версии, завершённого deprecation/sunset и подтверждённого нулевого использования. Политика и журнал изменений хранятся в репозитории в `docs/api-versioning-and-deprecation.md` и `docs/api-changelog.md`.

## Карта документа

1. Создайте workspace в кабинете и настройте программу.
2. Добавьте торговую точку и терминал ЭВОТОР.
3. Выпустите отдельный ключ для кассы; компания определяется самим ключом.
4. Зарегистрируйте клиента только после OTP, затем проведите тестовый quote → hold → commit.
5. Подключите Mini App, Apple/Google Wallet и уведомления только после настройки соответствующих provider credentials.

## Модель данных и жизненный цикл чека

- `Tenant / Company` изолирует данные одной компании; одна компания может иметь много точек и касс ЭВОТОР.
- `Customer / Membership` создаётся после подтверждения телефона и связывает клиента с программой.
- Баланс строится из ledger и партий баллов, а не из одного изменяемого числа; партии поддерживают отложенную активацию и сгорание.
- Активная policy version — единый источник настроек для кабинета, API и APK. Quote сохраняет `policyVersionId`, поэтому новая настройка не переписывает старый чек.
- Денежный путь: `checkout session → quote → hold → commit`; возврат восстанавливает списанное и сторнирует начисленное.

## Настройки программы и формулы

| Поле | Фактическое действие |
|---|---|
| `rewardRate` | В режиме `PERCENT`: база начисления × ставка; 5% передаётся как `0.05`. |
| `accrualMode` | `NONE` отключает начисление, `PERCENT` использует ставку, `SPEND_STEP` начисляет фиксированные баллы за полный шаг суммы. |
| `discountPercent` | Построчная автоматическая скидка до списания баллов. |
| `maxDebitPercent` | Максимальная доля суммы после скидок, доступная для оплаты баллами. |
| `minimumRewardDebit` | Ниже порога списание становится нулевым. |
| `rewardDebitMultiplicity` | Максимум и запрос округляются вниз до заданного шага. |
| `rewardCreditBase` | `GROSS` — исходная сумма, `PAYABLE` — итог после скидок и списания. |
| `rewardRoundingMode` | Копейки без округления, математическое целое или округление вниз до целого. |
| флаги совмещения | Запрещают скидку, начисление или списание при внешней скидке и/или списании баллов. |
| `rewardActivationDelayDays` / `rewardLifetimeDays` | Определяют дату доступности и период жизни бонусов. |
| `rewardExpirationMode` | `NEVER` не задаёт дату, `AFTER_ACCRUAL` ведёт отдельные партии, `AFTER_LAST_PURCHASE` переносит единый срок только обычного покупочного баланса при каждом commit. |
| product exclusion campaign | У выбранных товаров, потомков группы и товаров с выбранной меткой одновременно отключает внутреннюю скидку, начисление и списание; остальной чек продолжает рассчитываться. |

Проверенный сквозной пример: чек `1000.00`, скидка 10%, максимум списания 30%, кратность 25 и запрос 500 дают скидку `100.00`, максимум и списание `250.00`, итог `650.00`; начисление 7,5% от `PAYABLE` с округлением `DOWN` равно `48.00`.

## ЭВОТОР, Mini App и Wallet

- Нативный checkout принимает только `sourceSystem=EVOTOR`. Для каждой кассы выпускайте отдельный минимально привилегированный ключ.
- APK получает построчный quote, применяет скидку, резервирует баллы через hold и подтверждает закрытый фискальный чек через commit.
- Telegram Mini App показывает баланс и QR без хранения tenant API-key в браузере; клиентская авторизация выполняется через отдельную customer session.
- Apple Wallet требует Pass Type ID, сертификат и WWDR; Google Wallet — issuer ID и service account. Без credentials API честно сообщает `NOT_CONFIGURED`.
- Геокоординаты точек входят в карту, но фактический proximity prompt контролируется ОС и настройками устройства.

## Готовность к production-запуску

В коде реализованы API, мультитенантность, OTP, ledger, checkout/возвраты, кабинет, Mini App API, Wallet contracts, APK ЭВОТОР, подписочный gate и аудит. Для коммерческого запуска всё ещё нужны платёжный provider, Apple/Google issuer credentials, реальные SMS/Telegram credentials, физическая приёмка APK на выбранной модели ЭВОТОР и differential-тесты с аккаунтом BonusPlus клиента.

## Авторизация

Для `/v1/*` передавайте tenant-ключ только с backend или доверенной кассы:

```http
Authorization: Bearer loy_live_…
```

Для `/compat/bonusplus/*` поддерживается формат BonusPlus:

```http
Authorization: ApiKey <base64(loy_live_…)>
```

Сырой `loy_live_…` после `ApiKey` принимается как безопасное расширение. Ключ определяет компанию; `tenantId` из пользовательского body не доверяется. Секрет нельзя хранить в Telegram Mini App, браузере, публичном репозитории или логах.

`policies:write` не входит в обычный или бессрочный ключ. Для управляемой миграции правил выпускается отдельный credential со сроком не более 24 часов; обычные интеграции используют только `policies:read`.

## Подписка, OTP и повтор запросов

- При неактивной подписке защищённые операции возвращают `403 subscription_inactive`; billing-exempt компания продолжает работать бессрочно.
- Регистрация и защищённые действия завершаются только после успешной проверки OTP. Канал должен быть реально настроен; иначе возвращается `503 notification_channel_unavailable`.
- Денежные и бонусные суммы передавайте десятичными строками, например `"250.00"`, без float-округления.
- Для операций с `Idempotency-Key` повторяйте тот же ключ только с идентичным payload. Другой payload получает `409`.
- QR/Wallet download token короткоживущий и не заменяет tenant API-ключ.

## Формат ошибок

Нативный API возвращает стабильный объект `{type, title, status, code, detail, requestId, errors}`. Совместимый фасад возвращает BonusPlus-формат `{msg, devMsg, code}` и заголовки часового лимита `X-RequestNumberLimit`, `X-RequestNumberRemain`, `X-RequestNumberReset`.

## Быстрый запрос

```bash
curl https://api.landlancer.online/v1/customers/search?phone=%2B79123456789 \
  -H "Authorization: Bearer $LOYALTY_API_KEY"
```

## Все endpoints

## Состояние сервиса

### `GET /health` — Проверить доступность API

Возвращает короткий ответ процесса без обращения к базе данных.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |

### `GET /ready` — Проверить готовность API

Проверяет соединение с PostgreSQL и возвращает готовность сервиса принимать запросы.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |

## 12K REST API

### `GET /v1/api-credentials` — Получить API-ключи

Возвращает метаданные ключей без их секретных значений.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `credentials:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CredentialListResponse`](#schema-credentiallistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/api-credentials` — Выпустить API-ключ

Создаёт ключ с заданными scopes и показывает секрет ровно один раз.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `credentials:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateCredentialRequest`](#schema-createcredentialrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`IssuedCredentialResponse`](#schema-issuedcredentialresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/api-credentials/{credential_id}/rotate` — Ротировать API-ключ

Отзывает старый credential и однократно возвращает новый секрет.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `credentials:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `credential_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`IssuedCredentialResponse`](#schema-issuedcredentialresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/card-types` — Получить типы карт

Возвращает tenant-scoped уровни программы и их активные неизменяемые версии экономики, сроков и защитных лимитов.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=10000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CardTypeListResponse`](#schema-cardtypelistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/card-types` — Создать тип карты

Создаёт новый ручной или накопительный уровень с собственной экономикой и лимитами; операция требует короткоживущий credential настройки политики.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CardTypeMutationRequest`](#schema-cardtypemutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CardTypeResponse`](#schema-cardtyperesponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/card-types/{card_type_id}` — Создать новую версию типа карты

Архивирует прежние правила и публикует следующую версию с optimistic concurrency через If-Match.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `card_type_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CardTypeMutationRequest`](#schema-cardtypemutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CardTypeResponse`](#schema-cardtyperesponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/cashiers` — Получить кассиров ЭВОТОР

Возвращает безопасный каталог авторизованных пользователей касс ЭВОТОР текущей компании. PIN, телефон и ИНН пользователя ЭВОТОР не принимаются и не сохраняются.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `page` | `query` | нет | integer; min=1, default=1 |
| `pageSize` | `query` | нет | integer; min=1, max=200, default=50 |
| `query` | `query` | нет | string; maxLength=100 \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CashierListResponse`](#schema-cashierlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/catalog-syncs` — Полностью синхронизировать каталог точки ЭВОТОР

Атомарно сверяет полный снимок товаров одной зарегистрированной точки ЭВОТОР: обновляет переданные позиции и удаляет отсутствующие. Требует Idempotency-Key; пустой снимок принимается только с явным allowEmpty=true.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `products:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=1, maxLength=128 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CatalogSyncRequest`](#schema-catalogsyncrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CatalogSyncResponse`](#schema-catalogsyncresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/checkout-sessions` — Открыть кассовую сессию

Создаёт идемпотентный checkout для чека ЭВОТОР и выбранного клиента.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateCheckoutSessionRequest`](#schema-createcheckoutsessionrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CheckoutSessionResponse`](#schema-checkoutsessionresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/checkout-sessions/{checkout_session_id}/commit` — Закрыть продажу

Фиксирует продажу, списание и начисление бонусов по подтверждённому чеку ЭВОТОР.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `checkout_session_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CommitSaleRequest`](#schema-commitsalerequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`SaleResponse`](#schema-saleresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `DELETE /v1/checkout-sessions/{checkout_session_id}/hold` — Освободить резерв

Снимает hold бонусов при отмене оплаты; разрешён также для безопасного завершения после остановки подписки.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `checkout_session_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ReleaseHoldRequest`](#schema-releaseholdrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`HoldResponse`](#schema-holdresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/checkout-sessions/{checkout_session_id}/hold` — Зарезервировать бонусы

Ставит рассчитанную сумму списания в hold до закрытия чека.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `checkout_session_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateHoldRequest`](#schema-createholdrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`HoldResponse`](#schema-holdresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/checkout-sessions/{checkout_session_id}/quote` — Рассчитать чек

Рассчитывает скидку, доступное списание и будущее начисление по позициям чека; возвращает причину ограничения, не блокируя саму продажу.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `checkout_session_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateQuoteRequest`](#schema-createquoterequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`QuoteResponse`](#schema-quoteresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/company` — Получить компанию

Возвращает реквизиты компании текущего tenant.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `company:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CompanyResponse`](#schema-companyresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/consent-documents` — Получить документы согласий

Возвращает версии юридических текстов согласий.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ConsentDocumentListResponse`](#schema-consentdocumentlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/consent-documents` — Создать документ согласия

Публикует новую неизменяемую версию текста согласия.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateConsentDocumentRequest`](#schema-createconsentdocumentrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ConsentDocumentResponse`](#schema-consentdocumentresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/coupon-campaigns` — Получить купонные кампании

Возвращает tenant-scoped список кампаний одноразовых промокодов без раскрытия исходных значений кодов.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CouponCampaignListResponse`](#schema-couponcampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/coupon-campaigns` — Создать купонную кампанию

Создаёт версионную кампанию фиксированной или процентной скидки с периодом действия и лимитами использования.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CouponCampaignMutationRequest`](#schema-couponcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CouponCampaignResponse`](#schema-couponcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/coupon-campaigns/{campaign_id}` — Изменить купонную кампанию

Версионно изменяет кампанию через If-Match и сохраняет изменение в append-only аудите.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CouponCampaignMutationRequest`](#schema-couponcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CouponCampaignResponse`](#schema-couponcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/coupon-campaigns/{campaign_id}/audit-events` — Получить аудит купонной кампании

Возвращает append-only историю создания и изменения кампании с actor, revision и неизменяемыми before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CouponCampaignAuditListResponse`](#schema-couponcampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/coupon-campaigns/{campaign_id}/code-batches` — Выпустить одноразовые купонные коды

Идемпотентно выпускает ограниченную партию кодов и показывает исходные значения только в первом успешном ответе; endpoint защищён rate limit.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CouponCodeBatchRequest`](#schema-couponcodebatchrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CouponCodeBatchResponse`](#schema-couponcodebatchresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/coupon-campaigns/{campaign_id}/codes` — Получить реестр купонных кодов

Возвращает только идентификаторы, маски, состояние и статистику использования кодов; исходные секретные значения повторно не выдаются.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CouponCodeListResponse`](#schema-couponcodelistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/coupon-codes/{code_id}/revoke` — Отозвать купонный код

Идемпотентно отзывает код по непрозрачному идентификатору и сохраняет причину и actor в аудите.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `code_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RevokeCouponCodeRequest`](#schema-revokecouponcoderequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CouponCodeResponse`](#schema-couponcoderesponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers` — Получить список клиентов

Возвращает страницу клиентов с поиском и фильтром по доступному балансу.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `query` | `query` | нет | string; maxLength=100 \| null |
| `minimumAvailable` | `query` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=20 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CustomerDirectoryResponse`](#schema-customerdirectoryresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/customers` — Создать клиента

Регистрирует клиента по российскому номеру телефона и создаёт бонусный счёт.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateCustomerRequest`](#schema-createcustomerrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`CustomerResponse`](#schema-customerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers/search` — Найти клиента по телефону

Возвращает клиента и актуальный бонусный баланс по нормализованному телефону.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone` | `query` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CustomerResponse`](#schema-customerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers/{customer_id}/card-type-assignment` — Получить уровень клиента

Возвращает текущее назначение типа карты, его источник, revision и подтверждённый накопленный оборот.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CustomerCardTypeAssignmentResponse`](#schema-customercardtypeassignmentresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/customers/{customer_id}/card-type-assignment` — Назначить уровень клиенту

Версионно назначает тип карты и журналирует ручное изменение без пересчёта старых чеков.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CustomerCardTypeAssignmentRequest`](#schema-customercardtypeassignmentrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`CustomerCardTypeAssignmentResponse`](#schema-customercardtypeassignmentresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers/{customer_id}/consents` — Получить согласия клиента

Возвращает аудит согласий конкретного клиента.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ConsentListResponse`](#schema-consentlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/customers/{customer_id}/consents` — Зафиксировать согласие клиента

Записывает доказательство согласия после подходящего подтверждённого challenge.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RecordConsentRequest`](#schema-recordconsentrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ConsentEvidenceResponse`](#schema-consentevidenceresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/customers/{customer_id}/membership-card` — Выпустить карту лояльности

Создаёт или возвращает карту клиента с QR и короткоживущими ссылками Wallet.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `cards:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`MembershipCardResponse`](#schema-membershipcardresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers/{customer_id}/reward-account` — Получить бонусный счёт

Возвращает доступные, ожидающие и зарезервированные бонусы клиента.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`RewardAccountResponse`](#schema-rewardaccountresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/customers/{customer_id}/reward-activities` — Получить историю бонусов

Возвращает страницу операций бонусного ledger конкретного клиента.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=20 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`RewardActivityPageResponse`](#schema-rewardactivitypageresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/customers/{customer_id}/reward-adjustments` — Изменить баланс бонусов

Идемпотентно начисляет или списывает бонусы с обязательным основанием операции.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `ledger:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `customer_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=128 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RewardAdjustmentRequest`](#schema-rewardadjustmentrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`RewardAdjustmentResponse`](#schema-rewardadjustmentresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/membership-cards/resolve` — Распознать карту

Находит действующую карту, клиента и баланс по QR/штрихкоду.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `cards:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ResolveCardRequest`](#schema-resolvecardrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ResolvedCardResponse`](#schema-resolvedcardresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/membership-cards/{card_id}/rotate` — Перевыпустить карту

Меняет секрет QR и инвалидирует старое значение.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `cards:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `card_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`MembershipCardResponse`](#schema-membershipcardresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/nth-purchase-campaigns` — Получить акции по номеру покупки

Возвращает tenant-scoped разовые правила для точного порядкового номера покупки, включая расписание, товары, исключения, точки и типы карт.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthPurchaseCampaignListResponse`](#schema-nthpurchasecampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/nth-purchase-campaigns` — Создать акцию по номеру покупки

Создаёт разовую процентную скидку на точную lifetime-покупку; scope поддерживает включения и исключения товаров, метки, точки и типы карт.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`NthPurchaseCampaignMutationRequest`](#schema-nthpurchasecampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`NthPurchaseCampaignResponse`](#schema-nthpurchasecampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/nth-purchase-campaigns/{campaign_id}` — Изменить акцию по номеру покупки

Версионно изменяет правило через If-Match; checkout сериализует порядковые номера и сохраняет применённую ревизию в quote.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`NthPurchaseCampaignMutationRequest`](#schema-nthpurchasecampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthPurchaseCampaignResponse`](#schema-nthpurchasecampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/nth-purchase-campaigns/{campaign_id}/audit-events` — Получить аудит акции по номеру покупки

Возвращает append-only историю конфигурации с actor, revision и неизменяемыми before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthPurchaseCampaignAuditListResponse`](#schema-nthpurchasecampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/nth-unit-campaigns` — Получить количественные акции

Возвращает tenant-scoped правила вида «каждый N-й товар»: цикл, число льготных единиц, выгоду, расписание и товарные области.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthUnitCampaignListResponse`](#schema-nthunitcampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/nth-unit-campaigns` — Создать количественную акцию

Создаёт правило «1+1=3 / каждый N-й»: бесплатная единица, процентная скидка или фиксированная цена с расписанием и областью товаров, меток и точек.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`NthUnitCampaignMutationRequest`](#schema-nthunitcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`NthUnitCampaignResponse`](#schema-nthunitcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/nth-unit-campaigns/{campaign_id}` — Изменить количественную акцию

Версионно изменяет правило через If-Match; checkout выбирает кампанию детерминированно и сохраняет механику, ревизию и денежный результат в quote.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`NthUnitCampaignMutationRequest`](#schema-nthunitcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthUnitCampaignResponse`](#schema-nthunitcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/nth-unit-campaigns/{campaign_id}/audit-events` — Получить аудит количественной акции

Возвращает append-only историю конфигурации акции с actor, revision и неизменяемыми before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`NthUnitCampaignAuditListResponse`](#schema-nthunitcampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/place-directory` — Получить публичный каталог точек

Возвращает активные города и только явно опубликованные в MINIAPP торговые точки текущей компании.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PlaceDirectoryResponse`](#schema-placedirectoryresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/policies` — Получить версии правил

Возвращает историю и черновики правил программы.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PolicyListResponse`](#schema-policylistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/policies` — Создать версию правил

Создаёт новый неизменяемый черновик бонусной политики.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreatePolicyRequest`](#schema-createpolicyrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`PolicyResponse`](#schema-policyresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/policies/current` — Получить активные правила

Возвращает применяемую сейчас версию правил начисления, списания и сроков бонусов.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PolicyResponse`](#schema-policyresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/policies/{policy_id}/activate` — Активировать правила

Делает выбранную версию правил текущей для новых расчётов.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `policy_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PolicyResponse`](#schema-policyresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/product-exclusion-campaigns` — Получить товарные исключения

Возвращает tenant-scoped наборы товаров, групп и меток с областью действия: пустой storeIds означает все торговые точки.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ProductExclusionCampaignListResponse`](#schema-productexclusioncampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/product-exclusion-campaigns` — Создать товарное исключение

Создаёт набор импортированных товаров, групп и/или productLabels глобально либо для выбранных storeIds; группа охватывает потомков по pid, метка — товары из любых веток.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ProductExclusionCampaignMutationRequest`](#schema-productexclusioncampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ProductExclusionCampaignResponse`](#schema-productexclusioncampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/product-exclusion-campaigns/{campaign_id}` — Изменить товарное исключение

Версионно изменяет набор через If-Match: отсутствие storeIds сохраняет область, явный [] включает все точки; checkout доверяет только terminal credential.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ProductExclusionCampaignMutationRequest`](#schema-productexclusioncampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ProductExclusionCampaignResponse`](#schema-productexclusioncampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/product-exclusion-campaigns/{campaign_id}/audit-events` — Получить аудит товарного исключения

Возвращает append-only историю создания и изменения набора с actor, revision и неизменяемыми before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ProductExclusionCampaignAuditListResponse`](#schema-productexclusioncampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/program` — Получить программу лояльности

Возвращает основную конфигурацию программы текущей компании.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `program:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ProgramResponse`](#schema-programresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/referral-program` — Получить условия реферальной программы

Возвращает активность, уровни, формулы, срок наград и revision настроек; денежные условия изменяются только в защищённом кабинете владельца.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `program:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ReferralProgramResponse`](#schema-referralprogramresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/referrals` — Получить реферальные приглашения

Возвращает tenant-scoped страницу персональных приглашений и число подтверждённых регистраций без раскрытия телефона клиента.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=50 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ReferralInvitePageResponse`](#schema-referralinvitepageresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/referrals` — Выпустить реферальное приглашение

Создаёт или повторно возвращает подписанную персональную ссылку активного клиента для выбранной активной ссылки регистрации.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ReferralInviteCreateRequest`](#schema-referralinvitecreaterequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ReferralInviteResponse`](#schema-referralinviteresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/referrals/{invite_id}/revoke` — Отозвать реферальное приглашение

Отзывает активное приглашение по If-Match, сохраняя историю регистраций и уже проведённых наград.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `invite_id` | `path` | да | string; pattern=^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ReferralInviteResponse`](#schema-referralinviteresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/referrals/{invite_id}/rotate` — Сменить реферальную ссылку

Повышает версию приглашения по If-Match и немедленно делает прежние URL и QR недействительными.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `customers:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `invite_id` | `path` | да | string; pattern=^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ReferralInviteResponse`](#schema-referralinviteresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/reward-accrual-campaigns` — Получить акции повышенного начисления

Возвращает tenant-scoped правила временного процентного кешбэка, включая расписание, активацию и срок бонусов, товары, исключения, списки клиентов, точки и типы карт.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`RewardAccrualCampaignListResponse`](#schema-rewardaccrualcampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/reward-accrual-campaigns` — Создать акцию повышенного начисления

Создаёт временный процентный кешбэк со стратегией MAXIMUM, отдельной активацией и сроком бонусов, расписанием и tenant-scoped областью товаров, списков клиентов, точек и типов карт.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RewardAccrualCampaignMutationRequest`](#schema-rewardaccrualcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`RewardAccrualCampaignResponse`](#schema-rewardaccrualcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/reward-accrual-campaigns/{campaign_id}` — Изменить акцию повышенного начисления

Версионно изменяет правило через If-Match; checkout применяет его только когда начисление выгоднее базового, а результат и условия бонусного lot сохраняет в quote.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RewardAccrualCampaignMutationRequest`](#schema-rewardaccrualcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`RewardAccrualCampaignResponse`](#schema-rewardaccrualcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/reward-accrual-campaigns/{campaign_id}/audit-events` — Получить аудит акции повышенного начисления

Возвращает append-only историю конфигурации с actor, revision и неизменяемыми before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`RewardAccrualCampaignAuditListResponse`](#schema-rewardaccrualcampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/sales/by-external-receipt/{external_receipt_id}` — Найти продажу по чеку ЭВОТОР

Возвращает зафиксированную продажу по внешнему идентификатору чека.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `external_receipt_id` | `path` | да | string; minLength=1, maxLength=128 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`SaleLookupResponse`](#schema-salelookupresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/sales/{sale_id}/returns` — Оформить возврат

Идемпотентно возвращает строки продажи и компенсирует бонусные операции.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `checkout:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `sale_id` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateReturnRequest`](#schema-createreturnrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ReturnResponse`](#schema-returnresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/scheduled-discount-campaigns` — Получить акции по расписанию

Возвращает tenant-scoped скидочные акции, их локальное расписание, приоритет и области товаров, меток и торговых точек.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ScheduledDiscountCampaignListResponse`](#schema-scheduleddiscountcampaignlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/scheduled-discount-campaigns` — Создать скидочную акцию по расписанию

Создаёт серверное правило скидки для счастливых часов: дни недели, локальный интервал, период дат, товары/группы/метки и точки; пустая товарная область означает весь чек.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ScheduledDiscountCampaignMutationRequest`](#schema-scheduleddiscountcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`ScheduledDiscountCampaignResponse`](#schema-scheduleddiscountcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /v1/scheduled-discount-campaigns/{campaign_id}` — Изменить скидочную акцию по расписанию

Версионно изменяет акцию через If-Match; checkout не суммирует акции, выбирает приоритетную и сохраняет неизменяемый снимок на строке quote.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `If-Match` | `header` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ScheduledDiscountCampaignMutationRequest`](#schema-scheduleddiscountcampaignmutationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ScheduledDiscountCampaignResponse`](#schema-scheduleddiscountcampaignresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/scheduled-discount-campaigns/{campaign_id}/audit-events` — Получить аудит акции по расписанию

Возвращает append-only историю конфигурации акции с actor, revision и before/after снимками.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `policies:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `campaign_id` | `path` | да | string |
| `offset` | `query` | нет | integer; min=0, max=1000000, default=0 |
| `limit` | `query` | нет | integer; min=1, max=100, default=100 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`ScheduledDiscountCampaignAuditListResponse`](#schema-scheduleddiscountcampaignauditlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/stores` — Получить торговые точки

Возвращает страницу точек текущей компании.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `page` | `query` | нет | integer; min=1, default=1 |
| `pageSize` | `query` | нет | integer; min=1, max=200, default=50 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`StoreListResponse`](#schema-storelistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/stores` — Создать торговую точку

Добавляет точку продаж, адрес и координаты для касс и Wallet-геометок.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateStoreRequest`](#schema-createstorerequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`StoreResponse`](#schema-storeresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/subscription` — Получить подписку

Возвращает тариф, лимит касс, статус и сроки доступа к API.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `subscription:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`SubscriptionResponse`](#schema-subscriptionresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/terminals` — Получить кассы

Возвращает страницу терминалов с фильтром по точке.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `page` | `query` | нет | integer; min=1, default=1 |
| `pageSize` | `query` | нет | integer; min=1, max=200, default=50 |
| `storeId` | `query` | нет | string \| null |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`TerminalListResponse`](#schema-terminallistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/terminals` — Зарегистрировать кассу ЭВОТОР

Привязывает терминал ЭВОТОР к торговой точке в пределах тарифного лимита.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateTerminalRequest`](#schema-createterminalrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`TerminalResponse`](#schema-terminalresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PATCH /v1/terminals/{terminal_id}` — Изменить кассу

Обновляет название, состояние или привязку терминала.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `locations:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `terminal_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`UpdateTerminalRequest`](#schema-updateterminalrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`TerminalResponse`](#schema-terminalresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/verifications` — Запросить код подтверждения

Создаёт ограниченный по времени OTP challenge и отправляет код через настроенный SMS или Telegram-канал.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`RequestVerificationRequest`](#schema-requestverificationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`VerificationResponse`](#schema-verificationresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/verifications/telegram-contact` — Подтвердить контакт Telegram

Создаёт подтверждённый enrollment challenge только для доверенного Mini App bot после self-contact Telegram.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `telegram:verify`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=128 |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`TrustedTelegramContactRequest`](#schema-trustedtelegramcontactrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`VerificationResponse`](#schema-verificationresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/verifications/{challenge_id}/confirm` — Подтвердить код

Проверяет OTP, срок и число попыток; только после успеха разрешается защищённое действие.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `consents:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `challenge_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`ConfirmVerificationRequest`](#schema-confirmverificationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`VerificationResponse`](#schema-verificationresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /v1/webhook-endpoints` — Получить webhook-подписки

Возвращает активные исходящие webhook endpoints.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `webhooks:read`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`WebhookListResponse`](#schema-webhooklistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /v1/webhook-endpoints` — Создать webhook-подписку

Регистрирует HTTPS endpoint, события и однократно возвращает HMAC-секрет.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `webhooks:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

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

- `application/json` — [`CreateWebhookRequest`](#schema-createwebhookrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`IssuedWebhookResponse`](#schema-issuedwebhookresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `DELETE /v1/webhook-endpoints/{endpoint_id}` — Отключить webhook

Деактивирует исходящую webhook-подписку.

- Авторизация: `Authorization: Bearer loy_live_…`
- Scope: `webhooks:write`
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `endpoint_id` | `path` | да | string |
| `X-Loyalty-Pos-Key` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`WebhookEndpointResponse`](#schema-webhookendpointresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

## BonusPlus compatibility — 40 операций

### 1. `GET /compat/bonusplus/account` — Получить аккаунт

Возвращает компанию, программу, подписку и цены каналов.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusAccountResponse`](#schema-bonusplusaccountresponse) |

### 2. `GET /compat/bonusplus/account/filter` — Получить справочники

Возвращает магазины, пол, типы операций и параметры программы.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusFilterDataResponse`](#schema-bonusplusfilterdataresponse) |

### 3. `POST /compat/bonusplus/certificate` — Создать сертификат

Выпускает подарочный сертификат с номиналом, остатком и сроком.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusCreateCertificateRequest`](#schema-bonuspluscreatecertificaterequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 4. `GET /compat/bonusplus/certificate/number` — Получить номер сертификата

Генерирует свободный EAN-13 для нового сертификата.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCertificateNumberResponse`](#schema-bonuspluscertificatenumberresponse) |

### 5. `DELETE /compat/bonusplus/certificate/{certificate_id}` — Удалить сертификат

Безопасно архивирует сертификат текущей компании.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `certificate_id` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 6. `GET /compat/bonusplus/certificate/{certificate_id}` — Получить сертификат

Возвращает состояние, номинал, остаток и срок сертификата.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `certificate_id` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCertificateResponse`](#schema-bonuspluscertificateresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 7. `GET /compat/bonusplus/customer` — Найти клиента

Ищет клиента по GUID, карте/EAN или телефону.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `id` | `query` | нет | string \| null |
| `ean` | `query` | нет | string \| null |
| `phone` | `query` | нет | string \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 8. `POST /compat/bonusplus/customer` — Создать клиента

Создаёт анкету, карту и бонусный счёт клиента.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusCreateCustomerRequest`](#schema-bonuspluscreatecustomerrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 9. `PUT /compat/bonusplus/customer/{phone_number}` — Заменить данные клиента

Заменяет поддерживаемые поля анкеты клиента.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |

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

- `application/json` — [`BonusPlusPutCustomerRequest`](#schema-bonusplusputcustomerrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 10. `PATCH /compat/bonusplus/customer/{phone_number}` — Изменить данные клиента

Частично обновляет анкету, телефон или карту.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |

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

- `application/json` — [`BonusPlusPatchCustomerRequest`](#schema-bonuspluspatchcustomerrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 11. `DELETE /compat/bonusplus/customer/{phone_number}` — Удалить клиента

Архивирует клиента и создаёт событие удаления.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 12. `PUT /compat/bonusplus/customer/{phone}/sendCode` — Отправить код по телефону

Создаёт OTP для указанного телефона через SMS-провайдера.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 13. `PUT /compat/bonusplus/customer/sendCode` — Отправить код из тела

Создаёт OTP для телефона из JSON-тела.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusSendCodeRequest`](#schema-bonusplussendcoderequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 14. `PUT /compat/bonusplus/customer/{phone_number}/checkCode/{code}` — Проверить код

Проверяет срок, попытки и подтверждает номер клиента.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |
| `code` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 15. `POST /compat/bonusplus/customer/list` — Получить список клиентов

Возвращает страницу Customer DTO; сложные CRM/RFM-фильтры реализованы не полностью.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusCustomerListRequest`](#schema-bonuspluscustomerlistrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: array<[`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse)> |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 16. `POST /compat/bonusplus/customer/{phone_number}/sendMessage` — Отправить сообщение

Ставит поддерживаемое сообщение в outbox; требуется реальный провайдер канала.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |

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

- `application/json` — [`BonusPlusSendMessageRequest`](#schema-bonusplussendmessagerequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 17. `POST /compat/bonusplus/customer/search` — Искать клиентов

Ищет до десяти клиентов по телефону или ФИО.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusCustomerSearchRequest`](#schema-bonuspluscustomersearchrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: array<[`BonusPlusDictionaryItemResponse`](#schema-bonusplusdictionaryitemresponse)> |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 18. `GET /compat/bonusplus/customer/stat` — Получить статистику клиентов

Возвращает агрегаты по полу, подтверждению, promo opt-out и e-card.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerStatsResponse`](#schema-bonuspluscustomerstatsresponse) |

### 19. `PATCH /compat/bonusplus/customer/{phone_number}/balance` — Изменить баланс

Начисляет или списывает бонусы с партиями и сроками.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=128 |

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

- `application/json` — [`BonusPlusBalancePatchRequest`](#schema-bonusplusbalancepatchrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusBalancePatchResponse`](#schema-bonusplusbalancepatchresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 20. `PATCH /compat/bonusplus/customer/{phone_number}/balance/reserve` — Зарезервировать бонусы

Создаёт или частично освобождает идемпотентный резерв.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=128 |

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

- `application/json` — [`BonusPlusReserveRequest`](#schema-bonusplusreserverequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 21. `DELETE /compat/bonusplus/customer/balance/reserve` — Отменить резерв

Полностью освобождает бонусный резерв.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusCancelReserveRequest`](#schema-bonuspluscancelreserverequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 22. `GET /compat/bonusplus/customer/{phone_number}/balance/reserve/{external_id}` — Получить резерв

Возвращает состояние и сумму резерва.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |
| `external_id` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusReserveResponse`](#schema-bonusplusreserveresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 23. `POST /compat/bonusplus/customer/login` — Войти как клиент

Проверяет телефон и scrypt-пароль с нейтральной ошибкой credentials.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusCustomerLoginRequest`](#schema-bonuspluscustomerloginrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 24. `GET /compat/bonusplus/customer/{phone}/setPassword` — Сбросить пароль

Генерирует пароль с rate limit и отправляет через настроенный SMS-канал.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 25. `GET /compat/bonusplus/ecard/{phone_number}/{valid_minutes}` — Получить e-card

Возвращает временную подписанную ссылку на QR-карту клиента.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `phone_number` | `path` | да | string |
| `valid_minutes` | `path` | да | number; max=10080.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusEcardLinkResponse`](#schema-bonusplusecardlinkresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 26. `PUT /compat/bonusplus/retail/calc` — Рассчитать продажу

Рассчитывает скидки, списание и начисление по строкам чека.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |

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

- `application/json` — [`BonusPlusRetailCalcRequest`](#schema-bonusplusretailcalcrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusRetailCalcResponse`](#schema-bonusplusretailcalcresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 27. `POST /compat/bonusplus/retail` — Провести продажу

Идемпотентно выполняет quote, hold и commit; сохраняет неизменяемый снимок даты, кассового контекста, тегов, купонов и товарных полей.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |

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

- `application/json` — [`BonusPlusRetailRequest`](#schema-bonusplusretailrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusRetailResponse`](#schema-bonusplusretailresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 28. `PUT /compat/bonusplus/retail/back` — Провести возврат

Возвращает всю оставшуюся часть выбранной строки либо указанную рублёвую сумму, компенсирует бонусы и выдаёт отдельный returnedPurchaseId.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `Idempotency-Key` | `header` | да | string; minLength=8, maxLength=100 |

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

- `application/json` — [`BonusPlusRetailBackRequest`](#schema-bonusplusretailbackrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusRetailBackResponse`](#schema-bonusplusretailbackresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 29. `POST /compat/bonusplus/retail/transactions` — Получить продажи и возвраты

Возвращает единый пагинированный поток строк продаж и возвратов с устойчивыми operation/position ID, датами, рублёвыми и бонусными суммами, историческим кассовым контекстом и tenant-safe фильтрами.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusTransactionFilterRequest`](#schema-bonusplustransactionfilterrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusTransactionListResponse`](#schema-bonusplustransactionlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 30. `POST /compat/bonusplus/retail/bonusActivities` — Получить бонусные операции

Возвращает операции бонусного ledger с устойчивыми person/purchase/store/cashier ID, историческим контекстом чека и карты, пагинацией и фильтрами phone, PersonsId, cardNumber, transactionType, creationDate и validUntil.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusActivityFilterRequest`](#schema-bonusplusactivityfilterrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusActivityListResponse`](#schema-bonusplusactivitylistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 31. `GET /compat/bonusplus/retail/{legacy_id}` — Получить продажу или возврат

Возвращает продажу type=0 либо возврат type=1 с parentId исходного чека, кассовым контекстом и неизменяемыми товарными позициями.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `legacy_id` | `path` | да | integer |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusSaleResponse`](#schema-bonusplussaleresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 32. `POST /compat/bonusplus/messaging/price` — Рассчитать цену сообщений

Считает GSM-7/UCS-2 сегменты и цену SMS/PUSH/EMAIL.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusMessagePriceRequest`](#schema-bonusplusmessagepricerequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusMessagePriceResponse`](#schema-bonusplusmessagepriceresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 33. `POST /compat/bonusplus/product/list` — Получить товары

Возвращает страницу товарного каталога.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusProductFilterRequest`](#schema-bonusplusproductfilterrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusProductListResponse`](#schema-bonusplusproductlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 34. `POST /compat/bonusplus/product/search` — Искать товары

Выполняет Unicode-регистронезависимый поиск по каталогу.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusProductSearchRequest`](#schema-bonusplusproductsearchrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusProductListResponse`](#schema-bonusplusproductlistresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 35. `POST /compat/bonusplus/product/import` — Импортировать товары

Массово обновляет или создаёт до 10 000 товаров.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusProductImportRequest`](#schema-bonusplusproductimportrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 36. `GET /compat/bonusplus/webhook/subscriptions` — Получить webhook-подписки

Возвращает активные совместимые подписки.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: array<[`BonusPlusWebhookResponse`](#schema-bonuspluswebhookresponse)> |

### 37. `GET /compat/bonusplus/webhook/subscription/{subscription_id}` — Получить webhook-подписку

Возвращает подписку текущей компании по ID.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `subscription_id` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusWebhookResponse`](#schema-bonuspluswebhookresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 38. `DELETE /compat/bonusplus/webhook/subscription/{subscription_id}` — Удалить webhook-подписку

Деактивирует совместимую подписку.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `subscription_id` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### 39. `POST /compat/bonusplus/webhook/subscription` — Создать webhook-подписку

Регистрирует HTTPS webhook с HMAC, retry и dead-letter доставкой.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `PARTIAL`

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

- `application/json` — [`BonusPlusWebhookCreateRequest`](#schema-bonuspluswebhookcreaterequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusWebhookResponse`](#schema-bonuspluswebhookresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `PUT /compat/bonusplus/retail/giftCard` — Найти сертификат для оплаты

Разрешает отдельно документированный BonusPlus gift-card tender по отсканированному номеру внутри текущей компании.

- Авторизация: `Authorization: ApiKey …`
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`BonusPlusGiftCardLookupRequest`](#schema-bonusplusgiftcardlookuprequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`BonusPlusCertificateResponse`](#schema-bonuspluscertificateresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

## Публичная регистрация, карты и Wallet

### `GET /public/v1/ecards/{download_token}` — Открыть электронную карту

По короткоживущему подписанному токену возвращает QR, баланс и геометки без API-ключа.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `download_token` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PublicEcardResponse`](#schema-publicecardresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/feedback/{token}` — Открыть форму отзыва

Проверяет одноразовую ссылку конкретного чека и возвращает только название компании, внешний номер чека, награду и срок.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `token` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=40, maxLength=64 |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PublicFeedbackContextResponse`](#schema-publicfeedbackcontextresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /public/v1/feedback/{token}` — Отправить отзыв и NPS

Однократно сохраняет рейтинг, NPS и комментарий; награда атомарно проходит через бонусный ledger и не может быть выдана повторно.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `token` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=40, maxLength=64 |

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

- `application/json` — [`PublicFeedbackSubmitRequest`](#schema-publicfeedbacksubmitrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`PublicFeedbackSubmitResponse`](#schema-publicfeedbacksubmitresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/feedback/{token}/operator-reply` — Получить ответ компании на отзыв

По исходной feedback capability до её срока действия возвращает доставленный ответ компании или явный статус ожидания без раскрытия других обращений клиента.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `token` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=40, maxLength=64 |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PublicFeedbackOperatorReplyResponse`](#schema-publicfeedbackoperatorreplyresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/legal-pages/{slug}` — Получить юридическую страницу

Возвращает последнюю утверждённую версию российского юридического документа, дата вступления в силу которой уже наступила; черновики и будущие версии не раскрываются.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `slug` | `path` | да | string; pattern=^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$ |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PublicLegalPageResponse`](#schema-publiclegalpageresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/legal-pages/{slug}.pdf` — Открыть юридический документ PDF

Отдаёт PDF последней утверждённой и уже действующей версии как application/pdf с проверяемым SHA-256; для текстовой версии и неопубликованной страницы возвращается 404.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `slug` | `path` | да | string; pattern=^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$ |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | Successful Response |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/plans` — Получить публичный каталог тарифов ЭВОТОР

Возвращает единый read-only каталог STANDARD, PROFI и PROFI_PLUS: цены на 1, 6 и 12 месяцев, стоимость дополнительной кассы и список возможностей. Оплату не запускает; тариф выдаётся вручную.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PlatformPlanCatalogResponse`](#schema-platformplancatalogresponse) |

### `GET /public/v1/registration/{slug}` — Открыть регистрацию клиента

По активной публичной ссылке возвращает бренд программы, тип карты, обязательные поля и актуальные версии документов согласия без раскрытия внутренних идентификаторов компании.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `slug` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=32, maxLength=43 |
| `ref` | `query` | нет | string; minLength=40, maxLength=160 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: [`PublicRegistrationConfigurationResponse`](#schema-publicregistrationconfigurationresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /public/v1/registration/{slug}/enroll` — Завершить регистрацию клиента

Проверяет одноразовый код и обязательные согласия, атомарно создаёт либо находит клиента, выпускает карту, начисляет настроенный приветственный бонус и возвращает баланс, QR и короткоживущую ссылку электронной карты.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `slug` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=32, maxLength=43 |
| `X-Public-Client-IP` | `header` | нет | string \| null |
| `X-Portal-BFF-Key` | `header` | нет | string \| null |
| `User-Agent` | `header` | нет | string \| null |

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

- `application/json` — [`PublicRegistrationEnrollRequest`](#schema-publicregistrationenrollrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`PublicRegistrationEnrollResponse`](#schema-publicregistrationenrollresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /public/v1/registration/{slug}/verifications` — Запросить код регистрации

Нормализует российский номер телефона, применяет лимиты по компании, ссылке, номеру и клиентскому адресу и отправляет одноразовый SMS-код; клиент до подтверждения не создаётся.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `slug` | `path` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=32, maxLength=43 |
| `X-Public-Client-IP` | `header` | нет | string \| null |
| `X-Portal-BFF-Key` | `header` | нет | string \| null |

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

- `application/json` — [`PublicRegistrationVerificationRequest`](#schema-publicregistrationverificationrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `201` | `application/json`: [`PublicRegistrationVerificationResponse`](#schema-publicregistrationverificationresponse) |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/wallet/apple/v1/devices/{device_library_identifier}/registrations/{pass_type_identifier}` — Получить изменившиеся Apple Wallet passes

Служебный PassKit endpoint: возвращает зарегистрированные serial numbers, изменившиеся после переданного монотонного update tag.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `device_library_identifier` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `pass_type_identifier` | `path` | да | string; pattern=^pass\.[A-Za-z0-9.-]+$, minLength=6, maxLength=255 |
| `passesUpdatedSince` | `query` | нет | string; maxLength=20 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `DELETE /public/v1/wallet/apple/v1/devices/{device_library_identifier}/registrations/{pass_type_identifier}/{serial_number}` — Отменить регистрацию Apple Wallet pass

Служебный PassKit endpoint: после проверки ApplePass-токена удаляет связь устройства с картой.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `device_library_identifier` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `pass_type_identifier` | `path` | да | string; pattern=^pass\.[A-Za-z0-9.-]+$, minLength=6, maxLength=255 |
| `serial_number` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `authorization` | `header` | нет | string; maxLength=600 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /public/v1/wallet/apple/v1/devices/{device_library_identifier}/registrations/{pass_type_identifier}/{serial_number}` — Зарегистрировать Apple Wallet pass

Служебный PassKit endpoint: проверяет ApplePass-токен, шифрует APNs push token и регистрирует устройство для обновлений карты.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `device_library_identifier` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `pass_type_identifier` | `path` | да | string; pattern=^pass\.[A-Za-z0-9.-]+$, minLength=6, maxLength=255 |
| `serial_number` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `authorization` | `header` | нет | string; maxLength=600 \| null |

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

- `application/json` — [`ApplePushTokenRequest`](#schema-applepushtokenrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `POST /public/v1/wallet/apple/v1/log` — Принять диагностическое сообщение Apple Wallet

Служебный PassKit endpoint: валидирует ограниченный пакет диагностических строк без сохранения пользовательского содержимого.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

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

- `application/json` — [`AppleLogEntriesRequest`](#schema-applelogentriesrequest) (обязательно)

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/wallet/apple/v1/passes/{pass_type_identifier}/{serial_number}` — Получить обновлённый Apple Wallet pass

Служебный PassKit endpoint: после проверки стабильного ApplePass-токена возвращает заново подписанный pass с актуальным QR и балансом.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `pass_type_identifier` | `path` | да | string; pattern=^pass\.[A-Za-z0-9.-]+$, minLength=6, maxLength=255 |
| `serial_number` | `path` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=255 |
| `authorization` | `header` | нет | string; maxLength=600 \| null |
| `if-modified-since` | `header` | нет | string; maxLength=128 \| null |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

### `GET /public/v1/wallet/apple/{download_token}` — Скачать Apple Wallet pass

По короткоживущему токену возвращает подписанный .pkpass; требует настроенного Apple issuer.

- Авторизация: не требуется
- Scope: не требуется
- Статус: `READY`

Параметры:

| Имя | Где | Обязателен | Тип / ограничения |
|---|---|---:|---|
| `download_token` | `path` | да | string |

Ответы:

| HTTP | Содержимое |
|---:|---|
| `200` | `application/json`: object |
| `422` | `application/json`: [`HTTPValidationError`](#schema-httpvalidationerror) |

## JSON-схемы

Ниже перечислены все модели, на которые ссылаются публичные операции.

<a id="schema-applelogentriesrequest"></a>
### `AppleLogEntriesRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `logs` | да | array<string>; maxItems=20 |

<a id="schema-applepushtokenrequest"></a>
### `ApplePushTokenRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `pushToken` | да | string; pattern=^[A-Za-z0-9_-]+$, minLength=1, maxLength=512 |

<a id="schema-appliedcouponresponse"></a>
### `AppliedCouponResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `campaignId` | да | string |
| `campaignRevision` | да | integer |
| `campaignName` | да | string |
| `codeMask` | да | string |
| `benefit` | да | string = `PERCENT`, `FIXED_AMOUNT` |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `fixedAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `minimumSubtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-barcoderesponse"></a>
### `BarcodeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `format` | нет | string; default="QR_CODE" |
| `message` | да | string |
| `alternateText` | да | string |

<a id="schema-bonusplusaccountresponse"></a>
### `BonusPlusAccountResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `balance` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `tariff` | да | string |
| `username` | да | string |
| `companies` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `smsPrice` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `pushPrice` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplusactivityfilterrequest"></a>
### `BonusPlusActivityFilterRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | нет | string; maxLength=32 \| null |
| `PersonsId` | нет | array<integer>; maxItems=1000, default=[] |
| `cardNumber` | нет | string; maxLength=128 \| null |
| `transactionType` | нет | integer \| null |
| `startRow` | нет | integer; min=0.0, max=1000000.0, default=0 |
| `rowCount` | нет | integer; min=1.0, max=1000.0, default=100 |
| `sort` | нет | integer \| null |
| `creationDate` | нет | [`BonusPlusDateTimeInterval`](#schema-bonusplusdatetimeinterval) \| null |
| `validUntil` | нет | [`BonusPlusDateTimeInterval`](#schema-bonusplusdatetimeinterval) \| null |

<a id="schema-bonusplusactivitylistresponse"></a>
### `BonusPlusActivityListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `bonusActivities` | да | array<[`BonusPlusActivityResponse`](#schema-bonusplusactivityresponse)> |
| `total` | да | integer |

<a id="schema-bonusplusactivityresponse"></a>
### `BonusPlusActivityResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | integer |
| `personId` | да | integer |
| `purchaseId` | да | integer \| null |
| `amount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `transactionType` | да | integer |
| `receiptDate` | да | string; format=date-time |
| `validUntil` | да | string; format=date-time \| null |
| `description` | да | string |
| `level` | да | integer |
| `purchaseAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `cardName` | да | string |
| `storeId` | да | integer |
| `cashierId` | да | integer |
| `phoneNumber` | да | string |
| `remainAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `cardNumber` | да | string |
| `purchaseNumber` | да | integer \| null |
| `transactionName` | да | string |

<a id="schema-bonusplusbalancepatchrequest"></a>
### `BonusPlusBalancePatchRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `amount` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `transactionType` | нет | integer; default=0 |
| `activatedInDays` | нет | integer; min=0.0, max=3650.0, default=0 |
| `burnsInDays` | нет | integer; min=1.0, max=3650.0, default=365 |

<a id="schema-bonusplusbalancepatchresponse"></a>
### `BonusPlusBalancePatchResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phoneNumber` | да | string |
| `cardNumber` | да | string |
| `amount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `activatedInDays` | да | integer |
| `burnsInDays` | да | integer |
| `activeBonusBalance` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `inactiveBonusBalance` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `level` | да | integer |
| `transactionType` | да | integer |

<a id="schema-bonuspluscancelreserverequest"></a>
### `BonusPlusCancelReserveRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string; minLength=1, maxLength=128 |

<a id="schema-bonuspluscarddictionaryitem"></a>
### `BonusPlusCardDictionaryItem`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `issuePurchasesSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusCreditPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusDebitPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonuspluscertificatenumberresponse"></a>
### `BonusPlusCertificateNumberResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `number` | да | string |

<a id="schema-bonuspluscertificateresponse"></a>
### `BonusPlusCertificateResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `expireDate` | да | string; format=date-time |
| `status` | да | string |
| `currentBalance` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `initialBalance` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonuspluscreatecertificaterequest"></a>
### `BonusPlusCreateCertificateRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `number` | нет | string; maxLength=128 \| null |
| `nominal` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `balance` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `expirationDate` | да | string; format=date-time |

<a id="schema-bonuspluscreatecustomerrequest"></a>
### `BonusPlusCreateCustomerRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `parentphone` | нет | string; minLength=10, maxLength=32 \| null |
| `mn` | нет | string; maxLength=100 \| null |
| `sex` | нет | string; maxLength=16 \| null |
| `email` | нет | string; maxLength=254 \| null |
| `desc` | нет | string; maxLength=2000 \| null |
| `birthDay` | нет | string; maxLength=10 \| null |
| `profileInstagram` | нет | string; maxLength=500 \| null |
| `profileVkontakte` | нет | string; maxLength=500 \| null |
| `profileOdnoklassniki` | нет | string; maxLength=500 \| null |
| `address` | нет | string; maxLength=500 \| null |
| `utmSource` | нет | string; maxLength=200 \| null |
| `relatives` | нет | array<[`BonusPlusRelative`](#schema-bonusplusrelative)>; maxItems=50, default=[] |
| `significantDates` | нет | array<[`BonusPlusSignificantDate`](#schema-bonusplussignificantdate)>; maxItems=50, default=[] |
| `disablePromo` | нет | boolean; default=false |
| `storeId` | нет | string; maxLength=128 \| null |
| `store` | нет | string; maxLength=200 \| null |
| `cashierId` | нет | string; maxLength=128 \| null |
| `registrationSourceId` | нет | string; maxLength=128 \| null |
| `phone` | да | string; minLength=10, maxLength=32 |
| `ean` | нет | string; pattern=^(?:[0-9]{8}\|[0-9]{13})$ \| null |
| `regBonus` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `card` | нет | string; maxLength=100 \| null |
| `fn` | нет | string; maxLength=100 \| null |
| `ln` | нет | string; maxLength=100 \| null |
| `confirmed` | нет | boolean; default=false |
| `noRegNotification` | нет | boolean; default=false |
| `creditBonuses` | нет | boolean; default=true |
| `smsCreditBonuses` | нет | boolean; default=false |
| `verificationChallengeId` | нет | string; minLength=36, maxLength=36 \| null |

<a id="schema-bonuspluscustomerlistrequest"></a>
### `BonusPlusCustomerListRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `startRow` | нет | integer; min=0.0, max=1000000.0, default=0 |
| `rowCount` | нет | integer; min=1.0, max=1000.0, default=100 |

<a id="schema-bonuspluscustomerloginrequest"></a>
### `BonusPlusCustomerLoginRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `login` | да | string; minLength=10, maxLength=32 |
| `password` | да | string; minLength=1, maxLength=128 |

<a id="schema-bonuspluscustomerresponse"></a>
### `BonusPlusCustomerResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `multiplicityDebitBonus` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `phone` | да | string |
| `id` | да | string |
| `discountCardTypeId` | да | integer |
| `discountCardNumber` | да | string |
| `discountCardName` | да | string |
| `parentphone` | да | string \| null |
| `availableBonuses` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `notActiveBonuses` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `lastPurchaseDate` | да | string; format=date-time \| null |
| `firstPurchaseDate` | да | string; format=date-time \| null |
| `totalBonusCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `totalBonusDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `person` | да | [`BonusPlusPersonResponse`](#schema-bonuspluspersonresponse) |
| `purchasesTotalSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `purchasesSumToNextCard` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `nextCardName` | да | string \| null |
| `regressEnabled` | да | boolean |
| `bonusDebitDenided` | да | boolean |
| `nearestBonusesExpirationAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `avgPurchasesTotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `nearestBonusesExpirationDate` | да | string \| null |
| `purchasesCount` | да | integer |
| `confirmed` | да | boolean |
| `inviteCode` | да | string |
| `registrationSourceId` | да | string \| null |
| `baseDiscountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `baseBonusDebitPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `baseBonusCreditPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `telegramBotStatus` | да | integer |
| `telegramBotRegistrationDate` | да | string; format=date-time \| null |
| `maxBotStatus` | да | integer |
| `maxBotRegistrationDate` | да | string; format=date-time \| null |
| `eCardStatusID` | да | integer |
| `vkStatusID` | да | integer |
| `disableAllMessages` | да | boolean |
| `isBlocked` | да | boolean |
| `archived` | да | boolean |

<a id="schema-bonuspluscustomersearchrequest"></a>
### `BonusPlusCustomerSearchRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `search` | да | string; minLength=1, maxLength=100 |

<a id="schema-bonuspluscustomerstatsresponse"></a>
### `BonusPlusCustomerStatsResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `allCount` | да | integer |
| `menCount` | да | integer |
| `womanCount` | да | integer |
| `othersCount` | да | integer |
| `agreedToSMSCount` | да | integer |
| `notAgreedToSMSCount` | да | integer |
| `disablePromoCount` | да | integer |
| `enablePromoCount` | да | integer |
| `useEcardCount` | да | integer |
| `useEcardMenCount` | да | integer |
| `useEcardWomanCount` | да | integer |
| `useEcardOthersCount` | да | integer |

<a id="schema-bonusplusdatetimeinterval"></a>
### `BonusPlusDateTimeInterval`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `from` | да | string; format=date-time |
| `to` | да | string; format=date-time |

<a id="schema-bonusplusdictionaryitem"></a>
### `BonusPlusDictionaryItem`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |

<a id="schema-bonusplusdictionaryitemresponse"></a>
### `BonusPlusDictionaryItemResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |

<a id="schema-bonusplusecardlinkresponse"></a>
### `BonusPlusEcardLinkResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `url` | да | string |

<a id="schema-bonusplusfilterdataresponse"></a>
### `BonusPlusFilterDataResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cashiers` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `cards` | да | array<[`BonusPlusCardDictionaryItem`](#schema-bonuspluscarddictionaryitem)> |
| `stores` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `sexs` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `productLabels` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `productLabelsNew` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `personsList` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `templateTypes` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `finOperationTypes` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `bonusActivityTypes` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `registrationSources` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `segments` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `marketingActivities` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `activeSpecialOffers` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `specialOfferTags` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `segmentsTags` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `pendingTasks` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `significantDates` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |
| `tariffGroups` | да | array<[`BonusPlusDictionaryItem`](#schema-bonusplusdictionaryitem)> |

<a id="schema-bonusplusgiftcardlookuprequest"></a>
### `BonusPlusGiftCardLookupRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `number` | да | string; minLength=1, maxLength=128 |

<a id="schema-bonusplusgiftcardpaymentrequest"></a>
### `BonusPlusGiftCardPaymentRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string; minLength=1, maxLength=128 |
| `paymentSum` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |

<a id="schema-bonusplusmessagepricerequest"></a>
### `BonusPlusMessagePriceRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `type` | да | integer = `0`, `1`, `2` |
| `text` | да | string; minLength=1, maxLength=100000 |

<a id="schema-bonusplusmessagepriceresponse"></a>
### `BonusPlusMessagePriceResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `count` | да | integer |
| `price` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonuspluspatchcustomerrequest"></a>
### `BonusPlusPatchCustomerRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `parentphone` | нет | string; minLength=10, maxLength=32 \| null |
| `mn` | нет | string; maxLength=100 \| null |
| `sex` | нет | string; maxLength=16 \| null |
| `email` | нет | string; maxLength=254 \| null |
| `desc` | нет | string; maxLength=2000 \| null |
| `birthDay` | нет | string; maxLength=10 \| null |
| `profileInstagram` | нет | string; maxLength=500 \| null |
| `profileVkontakte` | нет | string; maxLength=500 \| null |
| `profileOdnoklassniki` | нет | string; maxLength=500 \| null |
| `address` | нет | string; maxLength=500 \| null |
| `utmSource` | нет | string; maxLength=200 \| null |
| `relatives` | нет | array<[`BonusPlusRelative`](#schema-bonusplusrelative)>; maxItems=50, default=[] |
| `significantDates` | нет | array<[`BonusPlusSignificantDate`](#schema-bonusplussignificantdate)>; maxItems=50, default=[] |
| `disablePromo` | нет | boolean; default=false |
| `storeId` | нет | string; maxLength=128 \| null |
| `store` | нет | string; maxLength=200 \| null |
| `cashierId` | нет | string; maxLength=128 \| null |
| `registrationSourceId` | нет | string; maxLength=128 \| null |
| `newPhone` | нет | string; minLength=10, maxLength=32 \| null |
| `cardNumber` | нет | string \| integer \| null |
| `cardPinCode` | нет | string; maxLength=128 \| null |
| `newCard` | нет | string; maxLength=100 \| null |
| `fn` | нет | string; maxLength=100 \| null |
| `ln` | нет | string; maxLength=100 \| null |

<a id="schema-bonuspluspersonresponse"></a>
### `BonusPlusPersonResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `fn` | да | string \| null |
| `ln` | да | string \| null |
| `mn` | да | string \| null |
| `sex` | да | string \| null |
| `email` | да | string \| null |
| `desc` | да | string \| null |
| `birthDay` | да | string \| null |
| `profileInstagram` | да | string \| null |
| `profileVkontakte` | да | string \| null |
| `profileOdnoklassniki` | да | string \| null |
| `address` | да | string \| null |
| `utmSource` | да | string \| null |
| `creationDate` | да | string; format=date-time |
| `lastUpdateDate` | да | string; format=date-time |
| `createdInStore` | да | string \| null |
| `disablePromoSMS` | да | boolean |
| `relatives` | да | array<[`BonusPlusRelative`](#schema-bonusplusrelative)> |
| `significantDates` | да | array<[`BonusPlusSignificantDate`](#schema-bonusplussignificantdate)> |
| `createdInStoreId` | да | integer \| null |
| `lastOperationStoreID` | да | integer \| null |
| `createdByCashierId` | да | integer \| null |

<a id="schema-bonusplusproductfilterrequest"></a>
### `BonusPlusProductFilterRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `store` | нет | string \| integer \| null |
| `parent` | нет | string; maxLength=128 \| null |
| `startRow` | нет | integer; min=0.0, max=1000000.0, default=0 |
| `rowCount` | нет | integer; min=1.0, max=1000.0, default=100 |

<a id="schema-bonusplusproductimportrequest"></a>
### `BonusPlusProductImportRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `products` | да | array<[`BonusPlusProductTinyRequest`](#schema-bonusplusproducttinyrequest)>; minItems=1, maxItems=10000 |
| `store` | да | string; minLength=1, maxLength=200 |

<a id="schema-bonusplusproductlistresponse"></a>
### `BonusPlusProductListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `products` | да | array<[`BonusPlusProductResponse`](#schema-bonusplusproductresponse)> |
| `total` | да | integer |

<a id="schema-bonusplusproductresponse"></a>
### `BonusPlusProductResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `store` | да | integer |
| `parent` | да | string \| null |
| `group` | да | boolean |
| `name` | да | string |
| `price` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplusproductsearchrequest"></a>
### `BonusPlusProductSearchRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `stores` | нет | array<integer>; maxItems=1000, default=[] |
| `text` | да | string; minLength=1, maxLength=500 |
| `withoutParent` | нет | boolean; default=false |

<a id="schema-bonusplusproducttinyrequest"></a>
### `BonusPlusProductTinyRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string; minLength=1, maxLength=128 |
| `pid` | нет | string; maxLength=128 \| null |
| `n` | да | string; minLength=1, maxLength=500 |
| `price` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `costPrice` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `g` | нет | boolean; default=false |
| `a` | нет | string; maxLength=128 \| null |
| `labels` | нет | array<string>; maxItems=100, default=[] |

<a id="schema-bonusplusputcustomerrequest"></a>
### `BonusPlusPutCustomerRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `parentphone` | нет | string; minLength=10, maxLength=32 \| null |
| `mn` | нет | string; maxLength=100 \| null |
| `sex` | нет | string; maxLength=16 \| null |
| `email` | нет | string; maxLength=254 \| null |
| `desc` | нет | string; maxLength=2000 \| null |
| `birthDay` | нет | string; maxLength=10 \| null |
| `profileInstagram` | нет | string; maxLength=500 \| null |
| `profileVkontakte` | нет | string; maxLength=500 \| null |
| `profileOdnoklassniki` | нет | string; maxLength=500 \| null |
| `address` | нет | string; maxLength=500 \| null |
| `utmSource` | нет | string; maxLength=200 \| null |
| `relatives` | нет | array<[`BonusPlusRelative`](#schema-bonusplusrelative)>; maxItems=50, default=[] |
| `significantDates` | нет | array<[`BonusPlusSignificantDate`](#schema-bonusplussignificantdate)>; maxItems=50, default=[] |
| `disablePromo` | нет | boolean; default=false |
| `storeId` | нет | string; maxLength=128 \| null |
| `store` | нет | string; maxLength=200 \| null |
| `cashierId` | нет | string; maxLength=128 \| null |
| `registrationSourceId` | нет | string; maxLength=128 \| null |
| `newPhone` | нет | string; minLength=10, maxLength=32 \| null |
| `newCardNumber` | нет | string \| integer \| null |
| `invitationCode` | нет | string; maxLength=128 \| null |
| `newCard` | нет | string; maxLength=100 \| null |
| `fn` | нет | string; maxLength=100 \| null |
| `ln` | нет | string; maxLength=100 \| null |
| `disableAllMessages` | нет | boolean; default=false |
| `isBlocked` | нет | boolean; default=false |
| `archived` | нет | boolean; default=false |

<a id="schema-bonusplusreceiptdiscountresponse"></a>
### `BonusPlusReceiptDiscountResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `ext` | да | string |
| `messages` | да | array<string> |
| `cb` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `db` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `ds` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `dp` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `ids` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `idp` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `dbp` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `cbp` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplusrelative"></a>
### `BonusPlusRelative`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `birthDay` | нет | string; maxLength=10 \| null |
| `sex` | нет | string; maxLength=16 \| null |
| `name` | да | string; minLength=1, maxLength=200 |

<a id="schema-bonusplusreserverequest"></a>
### `BonusPlusReserveRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string; minLength=1, maxLength=128 |
| `amount` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |

<a id="schema-bonusplusreserveresponse"></a>
### `BonusPlusReserveResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string |
| `id` | да | string |
| `amount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplusretailbackrequest"></a>
### `BonusPlusRetailBackRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `ext` | да | string; minLength=1, maxLength=128 |
| `sum` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `positionId` | нет | integer \| null |

<a id="schema-bonusplusretailbackresponse"></a>
### `BonusPlusRetailBackResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `returnedPurchaseId` | да | integer |

<a id="schema-bonusplusretailcalcrequest"></a>
### `BonusPlusRetailCalcRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `bonusDebit` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `items` | да | array<[`BonusPlusRetailItemRequest`](#schema-bonusplusretailitemrequest)>; minItems=1, maxItems=1000 |
| `level` | нет | integer; default=0 |
| `store` | нет | string; maxLength=128 \| null |
| `certificate` | нет | boolean; default=false |
| `coupons` | нет | array<string>; maxItems=100, default=[] |

<a id="schema-bonusplusretailcalcresponse"></a>
### `BonusPlusRetailCalcResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `discount` | да | array<[`BonusPlusReceiptDiscountResponse`](#schema-bonusplusreceiptdiscountresponse)> |
| `maxDebitBonuses` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `multiplicityDebitBonus` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplusretailitemrequest"></a>
### `BonusPlusRetailItemRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `sum` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `qnt` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,16}\|(?=[\d.]{1,21}0*$)\d{0,16}\.\d{0,4}0*$) |
| `product` | нет | string; maxLength=128 \| null |
| `ds` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `cat` | нет | string; maxLength=128 \| null |
| `label` | нет | string; maxLength=128 \| null |
| `ext` | нет | string; maxLength=128 \| null |
| `price` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `firstCost` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `costPrice` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `sellMode` | нет | string; maxLength=32 \| null |

<a id="schema-bonusplusretailrequest"></a>
### `BonusPlusRetailRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `items` | да | array<[`BonusPlusRetailItemRequest`](#schema-bonusplusretailitemrequest)>; minItems=1, maxItems=1000 |
| `bonusDebit` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `verificationChallengeId` | нет | string; minLength=36, maxLength=36 \| null |
| `externalId` | нет | string; maxLength=128 \| null |
| `tags` | нет | array<integer>; maxItems=100, default=[] |
| `desc` | нет | string; maxLength=500 \| null |
| `date` | нет | string; maxLength=64 \| null |
| `store` | нет | string; maxLength=128 \| null |
| `coupons` | нет | array<string>; maxItems=100, default=[] |
| `cashier` | нет | integer \| null |
| `certificate` | нет | boolean; default=false |
| `reserveId` | нет | string; maxLength=128 \| null |
| `giftCards` | нет | array<[`BonusPlusGiftCardPaymentRequest`](#schema-bonusplusgiftcardpaymentrequest)>; maxItems=100, default=[] |

<a id="schema-bonusplusretailresponse"></a>
### `BonusPlusRetailResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | integer |
| `orderUid` | да | string |
| `orderUrl` | да | string |
| `customer` | да | [`BonusPlusCustomerResponse`](#schema-bonuspluscustomerresponse) |

<a id="schema-bonusplussaleitemresponse"></a>
### `BonusPlusSaleItemResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `sum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `totalSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `qnt` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `product` | да | string |
| `productName` | да | string |
| `discount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `cat` | да | string |
| `ext` | да | string |
| `price` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `fc` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplussaleresponse"></a>
### `BonusPlusSaleResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | integer |
| `parentId` | да | integer \| null |
| `type` | да | integer |
| `date` | да | string; format=date-time |
| `customerPhone` | да | string |
| `cashierName` | да | string |
| `storeName` | да | string |
| `storeId` | да | integer |
| `totalSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `positions` | да | array<[`BonusPlusSaleItemResponse`](#schema-bonusplussaleitemresponse)> |

<a id="schema-bonusplussendcoderequest"></a>
### `BonusPlusSendCodeRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `variables` | нет | object |

<a id="schema-bonusplussendmessagerequest"></a>
### `BonusPlusSendMessageRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `message` | да | string; minLength=1, maxLength=4096 |
| `route` | нет | array<integer = `0`, `1`, `2`, `5`, `6`, `8`>; default=[0] |

<a id="schema-bonusplussignificantdate"></a>
### `BonusPlusSignificantDate`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | нет | string; maxLength=36 \| null |
| `significantDateId` | нет | string; maxLength=36 \| null |
| `significantDateType` | нет | integer \| null |
| `name` | да | string; minLength=1, maxLength=200 |
| `date` | да | string; format=date-time |
| `sex` | нет | integer \| null |

<a id="schema-bonusplustransactionfilterrequest"></a>
### `BonusPlusTransactionFilterRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `creationDate` | нет | array<[`BonusPlusDateTimeInterval`](#schema-bonusplusdatetimeinterval)>; maxItems=100, default=[] |
| `phone` | нет | array<string>; maxItems=1000, default=[] |
| `card` | нет | array<integer>; maxItems=1000, default=[] |
| `cashier` | нет | array<integer>; maxItems=1000, default=[] |
| `cardNumber` | нет | array<string>; maxItems=1000, default=[] |
| `store` | нет | array<integer>; maxItems=1000, default=[] |
| `person` | нет | array<integer>; maxItems=1000, default=[] |
| `externalId` | нет | string; maxLength=128 \| null |
| `startRow` | нет | integer; min=0.0, max=1000000.0, default=0 |
| `rowCount` | нет | integer; min=1.0, max=1000.0, default=100 |
| `sort` | нет | integer \| null |
| `purchaseNumber` | нет | integer; min=1.0 \| null |
| `purchaseNumbers` | нет | array<integer>; maxItems=1000, default=[] |
| `specialOffers` | нет | array<string; format=uuid>; maxItems=1000, default=[] |
| `fromSP` | нет | boolean \| null |

<a id="schema-bonusplustransactionlistresponse"></a>
### `BonusPlusTransactionListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `transactions` | да | array<[`BonusPlusTransactionResponse`](#schema-bonusplustransactionresponse)> |
| `total` | да | integer |
| `totalPurchaseCount` | да | integer |
| `totalAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `returnTotalAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `totalDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `totalBonusDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `totalBonusCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `showExternalPurchaseNumber` | да | boolean |
| `receiptCount` | да | integer |
| `receiptSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusCreditSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusDebitSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `receiptReturnCount` | да | integer |
| `receiptReturnSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `burnBonusCount` | да | integer |
| `burnBonusSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `birthdayBonusCount` | да | integer |
| `birthdayBonusSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reanimationBonusCount` | да | integer |
| `reanimationBonusSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `manualCreditBonusCount` | да | integer |
| `manualCreditBonusSum` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-bonusplustransactionresponse"></a>
### `BonusPlusTransactionResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `externalPurchaseNumber` | да | integer |
| `type` | да | integer |
| `externalId` | да | string |
| `positionId` | да | integer |
| `typeName` | да | string |
| `product` | да | string |
| `productName` | да | string |
| `remainAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `benefitInfo` | да | string |
| `productCategory` | да | string |
| `quantity` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `saleId` | да | integer |
| `date` | да | string; format=date-time |
| `purchaseAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `payment` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `bonusDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `cardName` | да | string |
| `storeId` | да | integer |
| `storeName` | да | string |
| `storeAddress` | да | string |
| `cashierId` | да | integer |
| `cashierName` | да | string |
| `phoneNumber` | да | string |
| `cardNumber` | да | string |
| `tags` | да | string |
| `customerFirstName` | да | string |
| `customerLastName` | да | string |
| `customerMiddleName` | да | string |
| `calculationUID` | да | string |

<a id="schema-bonuspluswebhookcreaterequest"></a>
### `BonusPlusWebhookCreateRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `eventId` | да | string = `ChangeCustomerBonusBalanceEvent`, `ChangeCustomerCardNumberEvent`, `CreateCustomerEvent`, `CreateSaleEvent`, `CustomerExpireBonusEvent`, `DeleteCustomerEvent`, `MakePurchaseBackEvent`, `NotifyCustomerEvent`, `UpdateCustomerEvent`, `sale.committed`, `return.committed`, `consent.changed`, `customer.balance_changed` |
| `url` | да | string; format=uri, minLength=1, maxLength=2048 |
| `httpMethod` | нет | string; default="POST" |
| `contentType` | нет | string; default="application/json" |
| `authorization` | нет | string; maxLength=2048, default="" |

<a id="schema-bonuspluswebhookresponse"></a>
### `BonusPlusWebhookResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `createTime` | да | string; format=date-time |
| `eventId` | да | string |
| `url` | да | string |
| `httpMethod` | да | string |
| `contentType` | да | string |
| `authorization` | да | string |

<a id="schema-cardlocationresponse"></a>
### `CardLocationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `storeId` | да | string |
| `name` | да | string |
| `latitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `longitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-cardtypelistresponse"></a>
### `CardTypeListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`CardTypeResponse`](#schema-cardtyperesponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-cardtypemutationrequest"></a>
### `CardTypeMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `code` | да | string; pattern=^[A-Z0-9_]+$, minLength=1, maxLength=32 |
| `name` | да | string; minLength=1, maxLength=100 |
| `branchCode` | нет | string; pattern=^[A-Z0-9_]+$, minLength=1, maxLength=32, default="MAIN" |
| `cashierAssignable` | нет | boolean; default=false |
| `assignmentMode` | да | string = `REGISTRATION`, `CUMULATIVE_SPEND`, `MANUAL` |
| `spendThreshold` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `priority` | нет | integer; min=0.0, max=1000000.0, default=0 |
| `presentation` | нет | [`CardTypePresentationRequest`](#schema-cardtypepresentationrequest) \| null |
| `rules` | да | [`CardTypeRulesRequest`](#schema-cardtyperulesrequest) |

<a id="schema-cardtypepresentationrequest"></a>
### `CardTypePresentationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `backgroundColor` | нет | string; pattern=^#[0-9A-Fa-f]{6}$, default="#FFFFFF" |
| `foregroundColor` | нет | string; pattern=^#[0-9A-Fa-f]{6}$, default="#000000" |
| `labelColor` | нет | string; pattern=^#[0-9A-Fa-f]{6}$, default="#006A44" |

<a id="schema-cardtypepresentationresponse"></a>
### `CardTypePresentationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `backgroundColor` | да | string |
| `foregroundColor` | да | string |
| `labelColor` | да | string |

<a id="schema-cardtyperesponse"></a>
### `CardTypeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `code` | да | string |
| `name` | да | string |
| `branchCode` | да | string |
| `isDefault` | да | boolean |
| `cashierAssignable` | да | boolean |
| `assignmentMode` | да | string |
| `spendThreshold` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `priority` | да | integer |
| `revision` | да | integer |
| `activeVersion` | да | [`CardTypeVersionResponse`](#schema-cardtypeversionresponse) |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-cardtyperulesrequest"></a>
### `CardTypeRulesRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `accrualMode` | нет | string = `NONE`, `PERCENT`, `SPEND_STEP`; default="PERCENT" |
| `rewardRate` | да | number; min=0.0, max=1.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,8}0*$)\d{0,3}\.\d{0,4}0*$) |
| `rewardStepAmount` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardStepBonus` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `maxDebitPercent` | да | number; min=0.0, max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `discountPercent` | нет | number; min=0.0, max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `minimumRewardDebit` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardDebitMultiplicity` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardActivationDelayDays` | нет | integer; min=0.0, max=3650.0, default=0 |
| `rewardLifetimeDays` | нет | integer; min=1.0, max=36500.0 \| null |
| `rewardExpirationMode` | нет | [`RewardExpirationMode`](#schema-rewardexpirationmode) |
| `registrationReward` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `limitsEnabled` | нет | boolean; default=false |
| `maxRewardDebitPer24Hours` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `maxPurchasesPerDay` | нет | integer; min=0.0, max=1000000.0 \| null |
| `maxPurchasesPerMonth` | нет | integer; min=0.0, max=10000000.0 \| null |
| `disableRewardCreditOnDebit` | нет | boolean; default=false |

<a id="schema-cardtyperulesresponse"></a>
### `CardTypeRulesResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `accrualMode` | да | string |
| `rewardRate` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardStepAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardStepBonus` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `maxDebitPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `minimumRewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardDebitMultiplicity` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardActivationDelayDays` | да | integer |
| `rewardLifetimeDays` | да | integer \| null |
| `rewardExpirationMode` | да | [`RewardExpirationMode`](#schema-rewardexpirationmode) |
| `registrationReward` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `limitsEnabled` | да | boolean |
| `maxRewardDebitPer24Hours` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `maxPurchasesPerDay` | да | integer \| null |
| `maxPurchasesPerMonth` | да | integer \| null |
| `disableRewardCreditOnDebit` | да | boolean |

<a id="schema-cardtypeversionresponse"></a>
### `CardTypeVersionResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `version` | да | integer |
| `status` | да | string |
| `rules` | да | [`CardTypeRulesResponse`](#schema-cardtyperulesresponse) |
| `presentation` | да | [`CardTypePresentationResponse`](#schema-cardtypepresentationresponse) |
| `createdAt` | да | string; format=date-time |
| `activatedAt` | да | string; format=date-time |

<a id="schema-cashierlistresponse"></a>
### `CashierListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`CashierResponse`](#schema-cashierresponse)> |
| `pagination` | да | [`PaginationResponse`](#schema-paginationresponse) |

<a id="schema-cashierresponse"></a>
### `CashierResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `externalId` | да | string |
| `firstName` | да | string \| null |
| `lastName` | да | string \| null |
| `displayName` | да | string |
| `roleExternalId` | да | string \| null |
| `roleTitle` | да | string \| null |
| `position` | да | string \| null |
| `firstSeenAt` | да | string; format=date-time |
| `lastSeenAt` | да | string; format=date-time |

<a id="schema-catalogsyncproductrequest"></a>
### `CatalogSyncProductRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `externalId` | да | string; minLength=1, maxLength=128 |
| `parentExternalId` | нет | string; maxLength=128 \| null |
| `name` | да | string; minLength=1, maxLength=500 |
| `price` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `costPrice` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `isGroup` | нет | boolean; default=false |
| `article` | нет | string; maxLength=128 \| null |
| `labels` | нет | array<string>; maxItems=100, default=[] |

<a id="schema-catalogsyncrequest"></a>
### `CatalogSyncRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `storeId` | да | string; minLength=36, maxLength=36 |
| `sourceRevision` | да | string; minLength=1, maxLength=128 |
| `allowEmpty` | нет | boolean; default=false |
| `products` | да | array<[`CatalogSyncProductRequest`](#schema-catalogsyncproductrequest)>; maxItems=10000 |

<a id="schema-catalogsyncresponse"></a>
### `CatalogSyncResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `storeId` | да | string |
| `storeName` | да | string |
| `sourceSystem` | да | string |
| `sourceRevision` | да | string |
| `productCount` | да | integer |
| `groupCount` | да | integer |
| `labelCount` | да | integer |
| `removedProductCount` | да | integer |
| `completedAt` | да | string; format=date-time |

<a id="schema-checkoutsessionresponse"></a>
### `CheckoutSessionResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `sessionId` | да | string |
| `status` | да | string |

<a id="schema-commitsalerequest"></a>
### `CommitSaleRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `quoteId` | да | string |
| `holdId` | да | string |
| `externalReceiptId` | да | string; minLength=1, maxLength=128 |

<a id="schema-companyresponse"></a>
### `CompanyResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `createdAt` | да | string; format=date-time |

<a id="schema-confirmverificationrequest"></a>
### `ConfirmVerificationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `code` | да | string; pattern=^[0-9]{6}$ |

<a id="schema-consentdocumentlistresponse"></a>
### `ConsentDocumentListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`ConsentDocumentResponse`](#schema-consentdocumentresponse)> |

<a id="schema-consentdocumentresponse"></a>
### `ConsentDocumentResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `purpose` | да | string |
| `version` | да | string |
| `title` | да | string |
| `body` | да | string |
| `bodyHash` | да | string |
| `requiresVerification` | да | boolean |
| `isActive` | да | boolean |
| `effectiveAt` | да | string; format=date-time |
| `createdAt` | да | string; format=date-time |

<a id="schema-consentevidenceresponse"></a>
### `ConsentEvidenceResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `customerId` | да | string |
| `documentId` | да | string |
| `purpose` | да | string |
| `version` | да | string |
| `action` | да | string |
| `source` | да | string |
| `evidenceHash` | да | string |
| `occurredAt` | да | string; format=date-time |

<a id="schema-consentlistresponse"></a>
### `ConsentListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`ConsentEvidenceResponse`](#schema-consentevidenceresponse)> |

<a id="schema-couponcampaignauditlistresponse"></a>
### `CouponCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`CouponCampaignAuditResponse`](#schema-couponcampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-couponcampaignauditresponse"></a>
### `CouponCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`CouponCampaignSnapshotResponse`](#schema-couponcampaignsnapshotresponse) \| null |
| `after` | да | [`CouponCampaignSnapshotResponse`](#schema-couponcampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-couponcampaignlistresponse"></a>
### `CouponCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`CouponCampaignResponse`](#schema-couponcampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-couponcampaignmutationrequest"></a>
### `CouponCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=false |
| `priority` | нет | integer; min=0.0, max=1000.0, default=100 |
| `benefit` | да | string = `PERCENT`, `FIXED_AMOUNT` |
| `discountPercent` | нет | number; max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) \| null |
| `fixedAmount` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `minimumSubtotal` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `startsAt` | да | string; format=date-time |
| `endsAt` | да | string; format=date-time |
| `maxRedemptionsTotal` | да | integer; min=1.0, max=2147483647.0 |
| `maxRedemptionsPerCode` | да | integer; min=1.0, max=2147483647.0 |
| `maxRedemptionsPerCustomer` | да | integer; min=1.0, max=2147483647.0 |

<a id="schema-couponcampaignresponse"></a>
### `CouponCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `benefit` | да | string = `PERCENT`, `FIXED_AMOUNT` |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `fixedAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `minimumSubtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `startsAt` | да | string; format=date-time |
| `endsAt` | да | string; format=date-time |
| `maxRedemptionsTotal` | да | integer |
| `maxRedemptionsPerCode` | да | integer |
| `maxRedemptionsPerCustomer` | да | integer |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-couponcampaignsnapshotresponse"></a>
### `CouponCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `benefit` | да | string = `PERCENT`, `FIXED_AMOUNT` |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `fixedAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `minimumSubtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `startsAt` | да | string; format=date-time |
| `endsAt` | да | string; format=date-time |
| `maxRedemptionsTotal` | да | integer |
| `maxRedemptionsPerCode` | да | integer |
| `maxRedemptionsPerCustomer` | да | integer |
| `revision` | да | integer |

<a id="schema-couponcodebatchrequest"></a>
### `CouponCodeBatchRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `quantity` | да | integer; min=1.0, max=1000.0 |
| `prefix` | нет | string; minLength=1, maxLength=8 \| null |

<a id="schema-couponcodebatchresponse"></a>
### `CouponCodeBatchResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `batchId` | да | string |
| `campaignId` | да | string |
| `quantity` | да | integer |
| `prefix` | да | string \| null |
| `codes` | да | array<[`IssuedCouponCodeResponse`](#schema-issuedcouponcoderesponse)> \| null |
| `isReplay` | да | boolean |
| `createdAt` | да | string; format=date-time |

<a id="schema-couponcodelistresponse"></a>
### `CouponCodeListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`CouponCodeResponse`](#schema-couponcoderesponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-couponcoderesponse"></a>
### `CouponCodeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `batchId` | да | string |
| `mask` | да | string |
| `status` | да | string = `ACTIVE`, `REVOKED` |
| `createdAt` | да | string; format=date-time |
| `revokedAt` | да | string; format=date-time \| null |

<a id="schema-createcheckoutsessionrequest"></a>
### `CreateCheckoutSessionRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `customerId` | да | string; minLength=1, maxLength=36 |
| `sourceSystem` | да | string |
| `externalSessionId` | нет | string; maxLength=128 \| null |
| `cashier` | нет | [`EvotorCashierRequest`](#schema-evotorcashierrequest) \| null |

<a id="schema-createconsentdocumentrequest"></a>
### `CreateConsentDocumentRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `purpose` | да | string = `TERMS`, `PERSONAL_DATA`, `MARKETING`, `E_RECEIPT` |
| `version` | да | string; pattern=^[A-Za-z0-9._-]+$, minLength=1, maxLength=32 |
| `title` | да | string; minLength=1, maxLength=200 |
| `body` | да | string; minLength=1, maxLength=100000 |
| `requiresVerification` | нет | boolean; default=true |
| `effectiveAt` | нет | string; format=date-time \| null |

<a id="schema-createcredentialrequest"></a>
### `CreateCredentialRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `label` | да | string; minLength=1, maxLength=100 |
| `scopes` | да | array<string>; minItems=1, maxItems=20 |
| `expiresAt` | нет | string; format=date-time \| null |

<a id="schema-createcustomerrequest"></a>
### `CreateCustomerRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `firstName` | нет | string; maxLength=100 \| null |
| `lastName` | нет | string; maxLength=100 \| null |
| `verificationChallengeId` | нет | string; minLength=36, maxLength=36 \| null |

<a id="schema-createholdrequest"></a>
### `CreateHoldRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `quoteId` | да | string |
| `verificationChallengeId` | нет | string; minLength=36, maxLength=36 \| null |

<a id="schema-createpolicyrequest"></a>
### `CreatePolicyRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `rewardRate` | да | number; min=0.0, max=1.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,8}0*$)\d{0,3}\.\d{0,4}0*$) |
| `maxDebitPercent` | да | number; min=0.0, max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `pointsPerRuble` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `accrualMode` | нет | string = `NONE`, `PERCENT`, `SPEND_STEP`; default="PERCENT" |
| `rewardStepAmount` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardStepBonus` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `discountPercent` | нет | number; min=0.0, max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `minimumRewardDebit` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardDebitMultiplicity` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `rewardCreditBase` | нет | string = `GROSS`, `PAYABLE`; default="GROSS" |
| `rewardRoundingMode` | нет | string = `NONE`, `MATHEMATICAL`, `DOWN`; default="NONE" |
| `requireRegistrationVerification` | нет | boolean; default=false |
| `requireRedemptionVerification` | нет | boolean; default=false |
| `disableRewardCreditOnDebit` | нет | boolean; default=false |
| `disableInternalDiscountOnDebit` | нет | boolean; default=false |
| `disableInternalDiscountOnExternal` | нет | boolean; default=false |
| `disableRewardCreditOnExternal` | нет | boolean; default=false |
| `disableRewardDebitOnExternal` | нет | boolean; default=false |
| `rewardActivationDelayDays` | нет | integer; min=0.0, max=3650.0, default=0 |
| `rewardLifetimeDays` | нет | integer; min=1.0, max=36500.0 \| null |
| `rewardExpirationMode` | нет | [`RewardExpirationMode`](#schema-rewardexpirationmode) |
| `cardRegressionEnabled` | нет | boolean; default=false |
| `cardRegressionDates` | нет | array<string; pattern=^\d{2}\.\d{2}$>; maxItems=366 |
| `cardRegressionTime` | нет | string; pattern=^(?:[01]\d\|2[0-3]):[0-5]\d$, default="00:00" |
| `cardRegressionWindowMonths` | нет | integer; min=1.0, max=120.0 \| null |

<a id="schema-createquoterequest"></a>
### `CreateQuoteRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `requestedRewardDebit` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `couponCode` | нет | string; minLength=6, maxLength=64 \| null |
| `lines` | да | array<[`QuoteLineRequest`](#schema-quotelinerequest)>; minItems=1, maxItems=1000 |

<a id="schema-createreturnrequest"></a>
### `CreateReturnRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `externalReturnId` | да | string; minLength=1, maxLength=128 |
| `lines` | нет | array<[`ReturnLineRequest`](#schema-returnlinerequest)>; minItems=1, maxItems=1000 \| null |

<a id="schema-createstorerequest"></a>
### `CreateStoreRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cityId` | нет | string; minLength=36, maxLength=36 \| null |
| `name` | да | string; minLength=1, maxLength=200 |
| `externalId` | нет | string; minLength=1, maxLength=128 \| null |
| `address` | нет | string; maxLength=500 \| null |
| `latitude` | нет | number; min=-90.0, max=90.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d{0,6}0*$ \| null |
| `longitude` | нет | number; min=-180.0, max=180.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d{0,6}0*$ \| null |
| `timezone` | нет | string; minLength=1, maxLength=64 \| null |

<a id="schema-createterminalrequest"></a>
### `CreateTerminalRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `storeId` | да | string; minLength=36, maxLength=36 |
| `name` | да | string; minLength=1, maxLength=200 |
| `sourceSystem` | да | string |
| `externalId` | да | string; minLength=1, maxLength=128 |

<a id="schema-createwebhookrequest"></a>
### `CreateWebhookRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `label` | да | string; minLength=1, maxLength=100 |
| `url` | да | string; format=uri, minLength=1, maxLength=2048 |
| `eventTypes` | да | array<string = `sale.committed`, `return.committed`, `consent.changed`, `customer.bonus_expiring`>; minItems=1, maxItems=20 |

<a id="schema-credentiallistresponse"></a>
### `CredentialListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`CredentialResponse`](#schema-credentialresponse)> |

<a id="schema-credentialresponse"></a>
### `CredentialResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `label` | да | string |
| `keyPrefix` | да | string |
| `scopes` | да | array<string> |
| `expiresAt` | да | string; format=date-time \| null |
| `createdAt` | да | string; format=date-time |
| `revokedAt` | да | string; format=date-time \| null |

<a id="schema-customercardtypeassignmentrequest"></a>
### `CustomerCardTypeAssignmentRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cardTypeId` | да | string; minLength=36, maxLength=36 |
| `automaticProgressionEnabled` | нет | boolean; default=false |

<a id="schema-customercardtypeassignmentresponse"></a>
### `CustomerCardTypeAssignmentResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `customerId` | да | string |
| `membershipId` | да | string |
| `source` | да | string |
| `automaticProgressionEnabled` | да | boolean |
| `revision` | да | integer |
| `assignedAt` | да | string; format=date-time |
| `cardType` | да | [`CardTypeResponse`](#schema-cardtyperesponse) |
| `progress` | да | [`LoyaltyProgressResponse`](#schema-loyaltyprogressresponse) |

<a id="schema-customerdirectoryresponse"></a>
### `CustomerDirectoryResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`CustomerResponse`](#schema-customerresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-customerresponse"></a>
### `CustomerResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `phone` | да | string |
| `firstName` | да | string \| null |
| `lastName` | да | string \| null |
| `confirmed` | да | boolean |
| `membershipId` | да | string |
| `createdAt` | да | string; format=date-time |
| `rewardAccount` | да | [`RewardAccountResponse`](#schema-rewardaccountresponse) |

<a id="schema-evotorcashierrequest"></a>
### `EvotorCashierRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `externalId` | да | string; minLength=1, maxLength=128 |
| `firstName` | нет | string; maxLength=200 \| null |
| `lastName` | нет | string; maxLength=200 \| null |
| `roleExternalId` | нет | string; maxLength=128 \| null |
| `roleTitle` | нет | string; maxLength=200 \| null |
| `position` | нет | string; maxLength=200 \| null |

<a id="schema-feedbackoperatorreplyresponse"></a>
### `FeedbackOperatorReplyResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `message` | да | string |
| `actorName` | да | string |
| `supportConversationId` | да | string \| null |
| `deliveryChannel` | да | string \| null |
| `deliveryStatus` | да | string \| null |
| `deliveredAt` | да | string; format=date-time \| null |
| `createdAt` | да | string; format=date-time |

<a id="schema-httpvalidationerror"></a>
### `HTTPValidationError`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `detail` | нет | array<[`ValidationError`](#schema-validationerror)> |

<a id="schema-holdresponse"></a>
### `HoldResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `holdId` | да | string |
| `amount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `status` | да | string |
| `expiresAt` | да | string; format=date-time |

<a id="schema-issuedcouponcoderesponse"></a>
### `IssuedCouponCodeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `code` | да | string |
| `mask` | да | string |

<a id="schema-issuedcredentialresponse"></a>
### `IssuedCredentialResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `credential` | да | [`CredentialResponse`](#schema-credentialresponse) |
| `apiKey` | да | string |

<a id="schema-issuedwebhookresponse"></a>
### `IssuedWebhookResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `endpoint` | да | [`WebhookEndpointResponse`](#schema-webhookendpointresponse) |
| `signingSecret` | да | string |

<a id="schema-loyaltyprogressresponse"></a>
### `LoyaltyProgressResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cumulativeSpend` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `purchaseCount` | да | integer |
| `updatedAt` | да | string; format=date-time |

<a id="schema-membershipcardartworkresponse"></a>
### `MembershipCardArtworkResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `url` | да | string |
| `digest` | да | string |
| `width` | да | integer |
| `height` | да | integer |

<a id="schema-membershipcardpresentationresponse"></a>
### `MembershipCardPresentationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cardTypeId` | да | string |
| `cardTypeVersionId` | да | string |
| `presentationVersion` | да | integer \| null |
| `backgroundColor` | да | string |
| `foregroundColor` | да | string |
| `labelColor` | да | string |
| `logo` | да | [`MembershipCardArtworkResponse`](#schema-membershipcardartworkresponse) \| null |
| `background` | да | [`MembershipCardArtworkResponse`](#schema-membershipcardartworkresponse) \| null |

<a id="schema-membershipcardresponse"></a>
### `MembershipCardResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `serialNumber` | да | string |
| `barcode` | да | [`BarcodeResponse`](#schema-barcoderesponse) |
| `physicalBarcode` | да | [`PhysicalBarcodeResponse`](#schema-physicalbarcoderesponse) |
| `locations` | да | array<[`CardLocationResponse`](#schema-cardlocationresponse)> |
| `wallets` | да | [`WalletsResponse`](#schema-walletsresponse) |
| `presentation` | да | [`MembershipCardPresentationResponse`](#schema-membershipcardpresentationresponse) |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-nthpurchasecampaignauditlistresponse"></a>
### `NthPurchaseCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`NthPurchaseCampaignAuditResponse`](#schema-nthpurchasecampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-nthpurchasecampaignauditresponse"></a>
### `NthPurchaseCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`NthPurchaseCampaignSnapshotResponse`](#schema-nthpurchasecampaignsnapshotresponse) \| null |
| `after` | да | [`NthPurchaseCampaignSnapshotResponse`](#schema-nthpurchasecampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-nthpurchasecampaignlistresponse"></a>
### `NthPurchaseCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`NthPurchaseCampaignResponse`](#schema-nthpurchasecampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-nthpurchasecampaignmutationrequest"></a>
### `NthPurchaseCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=true |
| `priority` | нет | integer; min=0.0, max=1000.0, default=100 |
| `purchaseNumber` | да | integer; min=1.0, max=1000.0 |
| `discountPercent` | да | number; max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `weekdays` | да | array<integer; min=0.0, max=6.0>; minItems=1, maxItems=7 |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | нет | string; format=date \| null |
| `endsOn` | нет | string; format=date \| null |
| `includedProductExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `excludedProductExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `productLabels` | нет | array<string>; maxItems=1000, default=[] |
| `storeIds` | нет | array<string>; maxItems=1000, default=[] |
| `cardTypeIds` | нет | array<string>; maxItems=1000, default=[] |

<a id="schema-nthpurchasecampaignresponse"></a>
### `NthPurchaseCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `purchaseNumber` | да | integer |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `includedProductExternalIds` | да | array<string> |
| `excludedProductExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `cardTypeIds` | да | array<string> |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-nthpurchasecampaignsnapshotresponse"></a>
### `NthPurchaseCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `purchaseNumber` | да | integer |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `includedProductExternalIds` | да | array<string> |
| `excludedProductExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `cardTypeIds` | да | array<string> |
| `revision` | да | integer |

<a id="schema-nthunitcampaignauditlistresponse"></a>
### `NthUnitCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`NthUnitCampaignAuditResponse`](#schema-nthunitcampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-nthunitcampaignauditresponse"></a>
### `NthUnitCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`NthUnitCampaignSnapshotResponse`](#schema-nthunitcampaignsnapshotresponse) \| null |
| `after` | да | [`NthUnitCampaignSnapshotResponse`](#schema-nthunitcampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-nthunitcampaignlistresponse"></a>
### `NthUnitCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`NthUnitCampaignResponse`](#schema-nthunitcampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-nthunitcampaignmutationrequest"></a>
### `NthUnitCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=true |
| `priority` | нет | integer; min=0.0, max=1000.0, default=100 |
| `cycleSize` | да | integer; min=2.0, max=1000.0 |
| `discountedUnits` | да | integer; min=1.0, max=999.0 |
| `benefit` | да | string = `FREE`, `PERCENT`, `FIXED_PRICE` |
| `discountPercent` | нет | number; max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) \| null |
| `fixedUnitPrice` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,12}\|(?=[\d.]{1,15}0*$)\d{0,12}\.\d{0,2}0*$) \| null |
| `weekdays` | да | array<integer; min=0.0, max=6.0>; minItems=1, maxItems=7 |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | нет | string; format=date \| null |
| `endsOn` | нет | string; format=date \| null |
| `productExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `productLabels` | нет | array<string>; maxItems=1000, default=[] |
| `storeIds` | нет | array<string>; maxItems=1000, default=[] |

<a id="schema-nthunitcampaignresponse"></a>
### `NthUnitCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `cycleSize` | да | integer |
| `discountedUnits` | да | integer |
| `benefit` | да | string = `FREE`, `PERCENT`, `FIXED_PRICE` |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `fixedUnitPrice` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-nthunitcampaignsnapshotresponse"></a>
### `NthUnitCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `cycleSize` | да | integer |
| `discountedUnits` | да | integer |
| `benefit` | да | string = `FREE`, `PERCENT`, `FIXED_PRICE` |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `fixedUnitPrice` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |

<a id="schema-paginationresponse"></a>
### `PaginationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `page` | да | integer |
| `pageSize` | да | integer |
| `totalItems` | да | integer |
| `totalPages` | да | integer |

<a id="schema-physicalbarcoderesponse"></a>
### `PhysicalBarcodeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `format` | да | string = `CODE128`, `EAN13`, `QR` |
| `message` | да | string |
| `alternateText` | да | string |

<a id="schema-placedirectorycityresponse"></a>
### `PlaceDirectoryCityResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `slug` | да | string |
| `name` | да | string |
| `mapImageUrl` | да | string \| null |
| `timezone` | да | string |
| `stores` | да | array<[`PlaceDirectoryStoreResponse`](#schema-placedirectorystoreresponse)> |

<a id="schema-placedirectoryresponse"></a>
### `PlaceDirectoryResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cities` | да | array<[`PlaceDirectoryCityResponse`](#schema-placedirectorycityresponse)> |

<a id="schema-placedirectorystoreresponse"></a>
### `PlaceDirectoryStoreResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `slug` | да | string |
| `name` | да | string |
| `address` | да | string \| null |
| `latitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `longitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `description` | да | string \| null |
| `hours` | да | object |

<a id="schema-platformplancatalogresponse"></a>
### `PlatformPlanCatalogResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`PlatformPlanResponse`](#schema-platformplanresponse)> |
| `currency` | нет | string; default="RUB" |
| `billingMode` | нет | string; default="MANUAL" |
| `sourceLabel` | да | string |
| `sourceUrl` | да | string |
| `compatibilityNote` | да | string |

<a id="schema-platformplanpriceresponse"></a>
### `PlatformPlanPriceResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `months` | да | integer = `1`, `6`, `12` |
| `firstTerminalRubles` | да | integer; min=0.0 |
| `additionalTerminalRubles` | да | integer; min=0.0 |

<a id="schema-platformplanresponse"></a>
### `PlatformPlanResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `code` | да | string = `STANDARD`, `PROFI`, `PROFI_PLUS` |
| `name` | да | string |
| `summary` | да | string |
| `prices` | да | array<[`PlatformPlanPriceResponse`](#schema-platformplanpriceresponse)> |
| `features` | да | array<string> |

<a id="schema-policylistresponse"></a>
### `PolicyListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`PolicyResponse`](#schema-policyresponse)> |

<a id="schema-policyresponse"></a>
### `PolicyResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `version` | да | integer |
| `status` | да | string |
| `rewardRate` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `maxDebitPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `pointsPerRuble` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `accrualMode` | да | string |
| `rewardStepAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardStepBonus` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `minimumRewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardDebitMultiplicity` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardCreditBase` | да | string |
| `rewardRoundingMode` | да | string |
| `requireRegistrationVerification` | да | boolean |
| `requireRedemptionVerification` | да | boolean |
| `disableRewardCreditOnDebit` | да | boolean |
| `disableInternalDiscountOnDebit` | да | boolean |
| `disableInternalDiscountOnExternal` | да | boolean |
| `disableRewardCreditOnExternal` | да | boolean |
| `disableRewardDebitOnExternal` | да | boolean |
| `rewardActivationDelayDays` | да | integer |
| `rewardLifetimeDays` | да | integer \| null |
| `rewardExpirationMode` | да | [`RewardExpirationMode`](#schema-rewardexpirationmode) |
| `cardRegressionEnabled` | да | boolean |
| `cardRegressionDates` | да | array<string> |
| `cardRegressionTime` | да | string |
| `cardRegressionWindowMonths` | да | integer \| null |
| `createdAt` | да | string; format=date-time |
| `activatedAt` | да | string; format=date-time \| null |

<a id="schema-productexclusioncampaignauditlistresponse"></a>
### `ProductExclusionCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`ProductExclusionCampaignAuditResponse`](#schema-productexclusioncampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-productexclusioncampaignauditresponse"></a>
### `ProductExclusionCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`ProductExclusionCampaignSnapshotResponse`](#schema-productexclusioncampaignsnapshotresponse) \| null |
| `after` | да | [`ProductExclusionCampaignSnapshotResponse`](#schema-productexclusioncampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-productexclusioncampaignlistresponse"></a>
### `ProductExclusionCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`ProductExclusionCampaignResponse`](#schema-productexclusioncampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-productexclusioncampaignmutationrequest"></a>
### `ProductExclusionCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=true |
| `productExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `productLabels` | нет | array<string>; maxItems=1000, default=[] |
| `storeIds` | нет | array<string>; maxItems=1000, default=[] |

<a id="schema-productexclusioncampaignresponse"></a>
### `ProductExclusionCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-productexclusioncampaignsnapshotresponse"></a>
### `ProductExclusionCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |

<a id="schema-programresponse"></a>
### `ProgramResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `currency` | да | string |
| `locale` | да | string |
| `timezone` | да | string |
| `createdAt` | да | string; format=date-time |

<a id="schema-publicconsentdocumentresponse"></a>
### `PublicConsentDocumentResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `purpose` | да | string = `PERSONAL_DATA`, `MARKETING` |
| `version` | да | string |
| `title` | да | string |
| `body` | да | string |
| `bodyHash` | да | string |

<a id="schema-publicecardresponse"></a>
### `PublicEcardResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `serialNumber` | да | string |
| `barcode` | да | [`BarcodeResponse`](#schema-barcoderesponse) |
| `physicalBarcode` | да | [`PhysicalBarcodeResponse`](#schema-physicalbarcoderesponse) |
| `locations` | да | array<[`CardLocationResponse`](#schema-cardlocationresponse)> |
| `expiresAt` | да | string; format=date-time |

<a id="schema-publicfeedbackcontextresponse"></a>
### `PublicFeedbackContextResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `companyName` | да | string |
| `receiptId` | да | string |
| `rewardAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `expiresAt` | да | string; format=date-time |

<a id="schema-publicfeedbackoperatorreplyresponse"></a>
### `PublicFeedbackOperatorReplyResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `status` | да | string = `PENDING`, `DELIVERED` |
| `reply` | да | [`FeedbackOperatorReplyResponse`](#schema-feedbackoperatorreplyresponse) \| null |

<a id="schema-publicfeedbacksubmitrequest"></a>
### `PublicFeedbackSubmitRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `rating` | да | integer; min=1.0, max=5.0 |
| `nps` | да | integer; min=0.0, max=10.0 |
| `comment` | нет | string; maxLength=2000 \| null |

<a id="schema-publicfeedbacksubmitresponse"></a>
### `PublicFeedbackSubmitResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `status` | да | string |
| `rewardAwarded` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `externalReviewUrl` | да | string \| null |

<a id="schema-publiclegalpageresponse"></a>
### `PublicLegalPageResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `slug` | да | string |
| `title` | да | string |
| `documentType` | да | string = `TERMS_OF_SERVICE`, `PRIVACY_NOTICE`, `PERSONAL_DATA_CONSENT`, `MARKETING_CONSENT`, `RETENTION_POLICY`, `PROCESSOR_AGREEMENT`, `OTHER` |
| `contentFormat` | да | string = `TEXT`, `PDF` |
| `content` | да | string \| null |
| `contentSha256` | да | string; pattern=^[0-9a-f]{64}$ |
| `effectiveFrom` | да | string; format=date-time |
| `version` | да | integer; min=1.0 |
| `pdfPath` | да | string \| null |

<a id="schema-publicregistrationbalanceresponse"></a>
### `PublicRegistrationBalanceResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `available` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `pending` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `held` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-publicregistrationcardtyperesponse"></a>
### `PublicRegistrationCardTypeResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `code` | да | string |
| `name` | да | string |
| `backgroundColor` | да | string |
| `foregroundColor` | да | string |
| `labelColor` | да | string |

<a id="schema-publicregistrationconfigurationresponse"></a>
### `PublicRegistrationConfigurationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `companyName` | да | string |
| `programName` | да | string |
| `cardType` | да | [`PublicRegistrationCardTypeResponse`](#schema-publicregistrationcardtyperesponse) |
| `registrationReward` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardExpiresInDays` | да | integer \| null |
| `referralApplied` | нет | boolean; default=false |
| `fields` | да | [`RegistrationFields`](#schema-registrationfields) |
| `personalDataDocument` | да | [`PublicConsentDocumentResponse`](#schema-publicconsentdocumentresponse) |
| `marketingDocument` | да | [`PublicConsentDocumentResponse`](#schema-publicconsentdocumentresponse) \| null |

<a id="schema-publicregistrationenrollrequest"></a>
### `PublicRegistrationEnrollRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `challengeId` | да | string; minLength=36, maxLength=36 |
| `code` | да | string; pattern=^[0-9]{6}$ |
| `firstName` | нет | string; maxLength=100 \| null |
| `lastName` | нет | string; maxLength=100 \| null |
| `email` | нет | string; maxLength=254 \| null |
| `birthDate` | нет | string; format=date \| null |
| `personalDataConsent` | да | boolean |
| `marketingConsent` | нет | boolean; default=false |
| `referralToken` | нет | string; pattern=^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$, minLength=40, maxLength=160 \| null |

<a id="schema-publicregistrationenrollresponse"></a>
### `PublicRegistrationEnrollResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `customerId` | да | string |
| `membershipId` | да | string |
| `isNewCustomer` | да | boolean |
| `phoneMasked` | да | string |
| `balance` | да | [`PublicRegistrationBalanceResponse`](#schema-publicregistrationbalanceresponse) |
| `card` | да | [`MembershipCardResponse`](#schema-membershipcardresponse) |
| `eCardUrl` | да | string |

<a id="schema-publicregistrationverificationrequest"></a>
### `PublicRegistrationVerificationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `referralToken` | нет | string; pattern=^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$, minLength=40, maxLength=160 \| null |

<a id="schema-publicregistrationverificationresponse"></a>
### `PublicRegistrationVerificationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `challengeId` | да | string |
| `phoneMasked` | да | string |
| `status` | да | string |
| `attemptsRemaining` | да | integer |
| `expiresAt` | да | string; format=date-time |
| `resendAfter` | да | string; format=date-time |
| `debugCode` | нет | string \| null |

<a id="schema-quotelinerequest"></a>
### `QuoteLineRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `lineId` | да | string; minLength=1, maxLength=128 |
| `productExternalId` | нет | string; maxLength=128 \| null |
| `quantity` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,16}\|(?=[\d.]{1,21}0*$)\d{0,16}\.\d{0,4}0*$) |
| `unitPrice` | да | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `externalDiscount` | нет | number; min=0.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |

<a id="schema-quotelineresponse"></a>
### `QuoteLineResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `lineId` | да | string |
| `loyaltyEligible` | да | boolean |
| `subtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `externalDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `internalDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `loyaltyDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `promotionId` | да | string \| null |
| `promotionRevision` | да | integer \| null |
| `promotionName` | да | string \| null |
| `promotionDiscountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `promotionMechanic` | да | string \| null |
| `promotionBenefit` | да | string \| null |
| `promotionDiscountAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `promotionCycleSize` | да | integer \| null |
| `promotionDiscountedUnits` | да | integer \| null |
| `promotionQualifyingUnits` | да | integer \| null |
| `promotionAwardedUnits` | да | integer \| null |
| `promotionFixedUnitPrice` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `promotionPurchaseNumber` | да | integer \| null |
| `rewardCampaignId` | да | string \| null |
| `rewardCampaignRevision` | да | integer \| null |
| `rewardCampaignName` | да | string \| null |
| `rewardCampaignRatePercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `rewardCampaignStrategy` | да | string \| null |
| `rewardCampaignActivationDelayDays` | да | integer \| null |
| `rewardCampaignExpirationDays` | да | integer \| null |
| `rewardCampaignMinimumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `rewardCampaignMaximumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `rewardCampaignQualifyingReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |

<a id="schema-quoteresponse"></a>
### `QuoteResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `quoteId` | да | string |
| `policyVersionId` | да | string |
| `cardTypeVersionId` | да | string \| null |
| `cardTypeCode` | да | string \| null |
| `cardTypeName` | да | string \| null |
| `inputHash` | да | string |
| `subtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `externalDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `internalDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `maximumRewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardDebitMultiplicity` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `loyaltyDiscount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `total` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `purchaseOrdinal` | да | integer \| null |
| `benefitsBlocked` | да | boolean |
| `limitReason` | да | string \| null |
| `rewardDebitLimitRemaining` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `coupon` | да | [`AppliedCouponResponse`](#schema-appliedcouponresponse) \| null |
| `expiresAt` | да | string; format=date-time |
| `lines` | да | array<[`QuoteLineResponse`](#schema-quotelineresponse)> |
| `rewardCampaignResults` | да | array<[`RewardCampaignResultResponse`](#schema-rewardcampaignresultresponse)> |

<a id="schema-recordconsentrequest"></a>
### `RecordConsentRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `documentId` | да | string; minLength=36, maxLength=36 |
| `verificationChallengeId` | нет | string; minLength=36, maxLength=36 \| null |
| `action` | да | string = `GRANTED`, `WITHDRAWN` |
| `source` | да | string = `POS`, `WEB`, `MOBILE`, `API` |
| `evidence` | нет | object |

<a id="schema-referralinvitecreaterequest"></a>
### `ReferralInviteCreateRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `inviterCustomerId` | да | string; pattern=^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ |
| `registrationLinkId` | да | string; pattern=^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ |

<a id="schema-referralinvitepageresponse"></a>
### `ReferralInvitePageResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`ReferralInviteResponse`](#schema-referralinviteresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-referralinviteresponse"></a>
### `ReferralInviteResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `inviterCustomerId` | да | string |
| `inviterName` | да | string |
| `inviterPhoneMasked` | да | string |
| `registrationLinkId` | да | string |
| `registrationLinkName` | да | string |
| `status` | да | string = `ACTIVE`, `REVOKED` |
| `tokenVersion` | да | integer |
| `inviteUrl` | да | string \| null |
| `registrationCount` | да | integer |
| `createdAt` | да | string; format=date-time |
| `rotatedAt` | да | string; format=date-time \| null |
| `revokedAt` | да | string; format=date-time \| null |

<a id="schema-referrallevelresponse"></a>
### `ReferralLevelResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `level` | да | integer |
| `kind` | да | string = `FIXED_POINTS`, `PERCENT_OF_PURCHASE_REWARD` |
| `value` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-referralprogramresponse"></a>
### `ReferralProgramResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `configured` | да | boolean |
| `status` | да | string = `ACTIVE`, `PAUSED` |
| `levels` | да | array<[`ReferralLevelResponse`](#schema-referrallevelresponse)> |
| `referredRegistrationReward` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `rewardExpiresInDays` | да | integer \| null |
| `revision` | да | integer |

<a id="schema-registrationfields"></a>
### `RegistrationFields`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `firstName` | нет | string = `HIDDEN`, `OPTIONAL`, `REQUIRED`; default="OPTIONAL" |
| `lastName` | нет | string = `HIDDEN`, `OPTIONAL`, `REQUIRED`; default="OPTIONAL" |
| `email` | нет | string = `HIDDEN`, `OPTIONAL`, `REQUIRED`; default="OPTIONAL" |
| `birthDate` | нет | string = `HIDDEN`, `OPTIONAL`, `REQUIRED`; default="OPTIONAL" |

<a id="schema-releaseholdrequest"></a>
### `ReleaseHoldRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `holdId` | да | string |

<a id="schema-requestverificationrequest"></a>
### `RequestVerificationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |
| `purpose` | да | string = `ENROLLMENT`, `CONSENT`, `CHECKOUT` |
| `channel` | да | string |
| `checkoutSessionId` | нет | string; minLength=36, maxLength=36 \| null |
| `quoteId` | нет | string; minLength=36, maxLength=36 \| null |

<a id="schema-resolvecardrequest"></a>
### `ResolveCardRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `token` | да | string; pattern=^card_live_[A-Za-z0-9_-]+$, minLength=32, maxLength=128 |

<a id="schema-resolvedcardresponse"></a>
### `ResolvedCardResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `cardId` | да | string |
| `customerId` | да | string |
| `membershipId` | да | string |
| `phone` | да | string |
| `firstName` | да | string \| null |
| `lastName` | да | string \| null |
| `rewardAccount` | да | [`RewardAccountResponse`](#schema-rewardaccountresponse) |

<a id="schema-returnlinerequest"></a>
### `ReturnLineRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `lineId` | да | string; minLength=1, maxLength=128 |
| `quantity` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,16}\|(?=[\d.]{1,21}0*$)\d{0,16}\.\d{0,4}0*$) |

<a id="schema-returnlineresponse"></a>
### `ReturnLineResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `lineId` | да | string |
| `quantity` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `returnedTotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `restoredRewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reversedRewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-returnresponse"></a>
### `ReturnResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `returnId` | да | string |
| `returnedSubtotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `returnedTotal` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `restoredRewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reversedRewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `restoredCertificateTender` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `saleStatus` | да | string |
| `lines` | да | array<[`ReturnLineResponse`](#schema-returnlineresponse)> |
| `rewardAccount` | да | [`RewardAccountResponse`](#schema-rewardaccountresponse) |

<a id="schema-revokecouponcoderequest"></a>
### `RevokeCouponCodeRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `reason` | да | string; minLength=1, maxLength=500 |

<a id="schema-rewardaccountresponse"></a>
### `RewardAccountResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `accountId` | да | string |
| `available` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `pending` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `held` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-rewardaccrualcampaignauditlistresponse"></a>
### `RewardAccrualCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`RewardAccrualCampaignAuditResponse`](#schema-rewardaccrualcampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-rewardaccrualcampaignauditresponse"></a>
### `RewardAccrualCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`RewardAccrualCampaignSnapshotResponse`](#schema-rewardaccrualcampaignsnapshotresponse) \| null |
| `after` | да | [`RewardAccrualCampaignSnapshotResponse`](#schema-rewardaccrualcampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-rewardaccrualcampaignlistresponse"></a>
### `RewardAccrualCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`RewardAccrualCampaignResponse`](#schema-rewardaccrualcampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-rewardaccrualcampaignmutationrequest"></a>
### `RewardAccrualCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=true |
| `priority` | нет | integer; min=0.0, max=1000.0, default=100 |
| `rewardRatePercent` | да | number; max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `strategy` | нет | string; default="MAXIMUM" |
| `activationDelayDays` | нет | integer; min=0.0, max=3650.0, default=0 |
| `expirationDays` | нет | integer; min=1.0, max=36500.0 \| null |
| `minimumReceiptAmount` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `maximumReceiptAmount` | нет | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) \| null |
| `minimumPurchaseOrdinal` | нет | integer; min=1.0, max=1000.0 \| null |
| `maximumPurchaseOrdinal` | нет | integer; min=1.0, max=1000.0 \| null |
| `resultChainCode` | нет | string; pattern=^[A-Za-z0-9][A-Za-z0-9_-]*$, minLength=1, maxLength=64, default="DEFAULT" |
| `resultGroupCode` | нет | string; pattern=^[A-Za-z0-9][A-Za-z0-9_-]*$, minLength=1, maxLength=64, default="DEFAULT" |
| `resultOrder` | нет | integer; min=0.0, max=1000.0, default=0 |
| `weekdays` | да | array<integer; min=0.0, max=6.0>; minItems=1, maxItems=7 |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | нет | string; format=date \| null |
| `endsOn` | нет | string; format=date \| null |
| `includedProductExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `excludedProductExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `productLabels` | нет | array<string>; maxItems=1000, default=[] |
| `storeIds` | нет | array<string>; maxItems=1000, default=[] |
| `cardTypeIds` | нет | array<string>; maxItems=1000, default=[] |
| `customerListIds` | нет | array<string>; maxItems=1000, default=[] |
| `customerIds` | нет | array<string>; maxItems=100, default=[] |

<a id="schema-rewardaccrualcampaignresponse"></a>
### `RewardAccrualCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `rewardRatePercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `strategy` | да | string |
| `activationDelayDays` | да | integer |
| `expirationDays` | да | integer \| null |
| `minimumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `maximumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `minimumPurchaseOrdinal` | да | integer \| null |
| `maximumPurchaseOrdinal` | да | integer \| null |
| `resultChainCode` | да | string |
| `resultGroupCode` | да | string |
| `resultOrder` | да | integer |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `includedProductExternalIds` | да | array<string> |
| `excludedProductExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `cardTypeIds` | да | array<string> |
| `customerListIds` | да | array<string> |
| `customerIds` | да | array<string> |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-rewardaccrualcampaignsnapshotresponse"></a>
### `RewardAccrualCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `rewardRatePercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `strategy` | да | string |
| `activationDelayDays` | да | integer |
| `expirationDays` | да | integer \| null |
| `minimumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `maximumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `minimumPurchaseOrdinal` | да | integer \| null |
| `maximumPurchaseOrdinal` | да | integer \| null |
| `resultChainCode` | да | string |
| `resultGroupCode` | да | string |
| `resultOrder` | да | integer |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `includedProductExternalIds` | да | array<string> |
| `excludedProductExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `cardTypeIds` | да | array<string> |
| `customerListIds` | да | array<string> |
| `customerIds` | да | array<string> |
| `revision` | да | integer |

<a id="schema-rewardactivitypageresponse"></a>
### `RewardActivityPageResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`RewardActivityResponse`](#schema-rewardactivityresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-rewardactivityresponse"></a>
### `RewardActivityResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `transactionId` | да | string |
| `operationType` | да | string |
| `amount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `reason` | да | string |
| `createdAt` | да | string; format=date-time |

<a id="schema-rewardadjustmentrequest"></a>
### `RewardAdjustmentRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `amount` | да | number \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,18}\|(?=[\d.]{1,21}0*$)\d{0,18}\.\d{0,2}0*$) |
| `reason` | да | string; minLength=3, maxLength=500 |
| `activateAt` | нет | string; format=date-time \| null |
| `expiresInDays` | нет | integer; min=1.0, max=3650.0 \| null |

<a id="schema-rewardadjustmentresponse"></a>
### `RewardAdjustmentResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `transactionId` | да | string |
| `accountId` | да | string |
| `available` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `pending` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `held` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-rewardcampaignresultresponse"></a>
### `RewardCampaignResultResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `lineId` | да | string |
| `campaignId` | да | string |
| `campaignRevision` | да | integer |
| `campaignName` | да | string |
| `configuredRatePercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `appliedRatePercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `resultChainCode` | да | string |
| `resultGroupCode` | да | string |
| `resultOrder` | да | integer |
| `minimumPurchaseOrdinal` | да | integer \| null |
| `maximumPurchaseOrdinal` | да | integer \| null |
| `purchaseOrdinal` | да | integer |
| `minimumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `maximumReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `qualifyingReceiptAmount` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |

<a id="schema-rewardexpirationmode"></a>
### `RewardExpirationMode`

Тип: string = `NEVER`, `AFTER_ACCRUAL`, `AFTER_LAST_PURCHASE`

<a id="schema-salelookupresponse"></a>
### `SaleLookupResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `saleId` | да | string |
| `status` | да | string |

<a id="schema-saleresponse"></a>
### `SaleResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `saleId` | да | string |
| `rewardDebit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardCredit` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `rewardAccount` | да | [`RewardAccountResponse`](#schema-rewardaccountresponse) |

<a id="schema-scheduleddiscountcampaignauditlistresponse"></a>
### `ScheduledDiscountCampaignAuditListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`ScheduledDiscountCampaignAuditResponse`](#schema-scheduleddiscountcampaignauditresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-scheduleddiscountcampaignauditresponse"></a>
### `ScheduledDiscountCampaignAuditResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `campaignId` | да | string |
| `actorType` | да | string = `PORTAL_USER`, `API_CREDENTIAL` |
| `actorId` | да | string |
| `action` | да | string = `CREATED`, `UPDATED` |
| `revision` | да | integer |
| `before` | да | [`ScheduledDiscountCampaignSnapshotResponse`](#schema-scheduleddiscountcampaignsnapshotresponse) \| null |
| `after` | да | [`ScheduledDiscountCampaignSnapshotResponse`](#schema-scheduleddiscountcampaignsnapshotresponse) |
| `createdAt` | да | string; format=date-time |

<a id="schema-scheduleddiscountcampaignlistresponse"></a>
### `ScheduledDiscountCampaignListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `items` | да | array<[`ScheduledDiscountCampaignResponse`](#schema-scheduleddiscountcampaignresponse)> |
| `total` | да | integer |
| `offset` | да | integer |
| `limit` | да | integer |

<a id="schema-scheduleddiscountcampaignmutationrequest"></a>
### `ScheduledDiscountCampaignMutationRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string; minLength=1, maxLength=120 |
| `isActive` | нет | boolean; default=true |
| `priority` | нет | integer; min=0.0, max=1000.0, default=100 |
| `discountPercent` | да | number; max=100.0 \| string; pattern=^(?!^[-+.]*$)[+-]?0*(?:\d{0,3}\|(?=[\d.]{1,6}0*$)\d{0,3}\.\d{0,2}0*$) |
| `weekdays` | да | array<integer; min=0.0, max=6.0>; minItems=1, maxItems=7 |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | нет | string; format=date \| null |
| `endsOn` | нет | string; format=date \| null |
| `productExternalIds` | нет | array<string>; maxItems=10000, default=[] |
| `productLabels` | нет | array<string>; maxItems=1000, default=[] |
| `storeIds` | нет | array<string>; maxItems=1000, default=[] |

<a id="schema-scheduleddiscountcampaignresponse"></a>
### `ScheduledDiscountCampaignResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-scheduleddiscountcampaignsnapshotresponse"></a>
### `ScheduledDiscountCampaignSnapshotResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `name` | да | string |
| `isActive` | да | boolean |
| `priority` | да | integer |
| `discountPercent` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ |
| `weekdays` | да | array<integer> |
| `localStartTime` | да | string; format=time |
| `localEndTime` | да | string; format=time |
| `startsOn` | да | string; format=date \| null |
| `endsOn` | да | string; format=date \| null |
| `productExternalIds` | да | array<string> |
| `productLabels` | да | array<string> |
| `storeIds` | да | array<string> |
| `revision` | да | integer |

<a id="schema-storelistresponse"></a>
### `StoreListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`StoreResponse`](#schema-storeresponse)> |
| `pagination` | да | [`PaginationResponse`](#schema-paginationresponse) |

<a id="schema-storeresponse"></a>
### `StoreResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `cityId` | да | string \| null |
| `name` | да | string |
| `externalId` | да | string \| null |
| `address` | да | string \| null |
| `latitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `longitude` | да | string; pattern=^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$ \| null |
| `timezone` | да | string |
| `status` | да | string |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-subscriptionresponse"></a>
### `SubscriptionResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `status` | да | string |
| `planCode` | да | string |
| `terminalLimit` | да | integer |
| `currentPeriodEndsAt` | да | string; format=date-time \| null |
| `graceEndsAt` | да | string; format=date-time \| null |
| `billingExempt` | да | boolean |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-terminallistresponse"></a>
### `TerminalListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`TerminalResponse`](#schema-terminalresponse)> |
| `pagination` | да | [`PaginationResponse`](#schema-paginationresponse) |

<a id="schema-terminalresponse"></a>
### `TerminalResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `storeId` | да | string |
| `name` | да | string |
| `sourceSystem` | да | string |
| `externalId` | да | string |
| `status` | да | string |
| `lastSeenAt` | да | string; format=date-time \| null |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-trustedtelegramcontactrequest"></a>
### `TrustedTelegramContactRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `phone` | да | string; minLength=10, maxLength=32 |

<a id="schema-updateterminalrequest"></a>
### `UpdateTerminalRequest`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `status` | да | string = `ACTIVE`, `INACTIVE` |

<a id="schema-validationerror"></a>
### `ValidationError`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `loc` | да | array<string \| integer> |
| `msg` | да | string |
| `type` | да | string |
| `input` | нет | object |
| `ctx` | нет | object |

<a id="schema-verificationresponse"></a>
### `VerificationResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `challengeId` | да | string |
| `phoneMasked` | да | string |
| `purpose` | да | string |
| `channel` | да | string |
| `status` | да | string |
| `attemptsRemaining` | да | integer |
| `expiresAt` | да | string; format=date-time |
| `resendAfter` | да | string; format=date-time |
| `verifiedAt` | да | string; format=date-time \| null |
| `debugCode` | нет | string \| null |

<a id="schema-walletplatformresponse"></a>
### `WalletPlatformResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `status` | да | string = `NOT_CONFIGURED`, `AVAILABLE` |
| `addUrl` | да | string \| null |

<a id="schema-walletsresponse"></a>
### `WalletsResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `apple` | да | [`WalletPlatformResponse`](#schema-walletplatformresponse) |
| `google` | да | [`WalletPlatformResponse`](#schema-walletplatformresponse) |

<a id="schema-webhookendpointresponse"></a>
### `WebhookEndpointResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `id` | да | string |
| `label` | да | string |
| `url` | да | string |
| `eventTypes` | да | array<string> |
| `isActive` | да | boolean |
| `createdAt` | да | string; format=date-time |
| `updatedAt` | да | string; format=date-time |

<a id="schema-webhooklistresponse"></a>
### `WebhookListResponse`

| Поле | Обязательно | Тип / ограничения |
|---|---:|---|
| `data` | да | array<[`WebhookEndpointResponse`](#schema-webhookendpointresponse)> |
