Общие концепции

offer_id, product_id, пагинация курсором, форматы дат и валют.

Общие правила вызова, фильтров, ошибок и id — как в DBS, для всех схем. Если в контракте этого нет, стоит пометка рекомендация.

Кто хранит товар, кто везёт покупателю и есть ли отгрузки — у DBS, FBS и FBO разное. Это не расхождение контракта, а разные схемы работы.

Как вызывать API

  • Все методы — POST. Тело и ответ — JSON (application/json). Пути вида /v1/….
  • Webhook в API нет. Новые заказы и смены статуса продавец опрашивает списком: обязательны filter и limit, cursor — чтобы взять следующую страницу.
  • Intro DBS: на MVP опрос заказов — POST /v1/order/dbs/list. Метод POST /v1/order/dbs/status/list в контракте есть; intro относит опрос событий «на будущее».
  • Адрес хоста в контракте — пример api.example.com. Боевой URL даёт витрина.

Авторизация — Bearer, см. авторизацию. Ошибки — обработка ошибок.

Схемы: не путать FBS и FBO

СхемаГде лежит товарКто собираетКто везёт покупателюЧто настраивает продавец
DBSСвой склад (location)ПродавецПродавец: курьер, ПВЗ, C&C, Express; зоны — полигоныСклады, полигоны, заказы. Отгрузок нет
FBSСклад продавца; сдача на склад маркетплейса (market_location_id)Продавец; в отгрузке грузоместа BOX или PALLETМаркетплейс после приёмки на своём складеОтгрузки, грузоместа, пропуск. Статусы отгрузки DRAFT … ACCEPTED / CANCELLED
FBOСклад маркетплейсаМаркетплейсМаркетплейсПоставка на склад маркетплейса, документы. Остатки без stock/update

FBS — не «продажа со склада маркетплейса». Продавец хранит и собирает у себя. Маркетплейс принимает отгрузку и везёт покупателю.

FBO — поставка на склады маркетплейса.

В DBS отгрузок и грузомест нет. Методы shipment/* и package/* — только FBS и FBO.

Один заказ — один товар (DBS и FBS)

Один заказ в API — один товар (offer_id, product_id). В списке заказов нет массива позиций: product_id, offer_id, product_name, prices висят на самом заказе.

item_type: PRODUCT или SERVICE. Для услуги может быть список связанных заказов linked_merchant_order_ids.

В FBS заказ тоже одна позиция. Несколько заказов кладут в одно грузоместо отгрузки.

Список заказов FBO — то, что маркетплейс уже ведёт со своего склада. Это не самовывоз DBS и не сдача FBS на склад маркетплейса.

Идентификаторы

ПолеЧто это
offer_idАртикул продавца
product_idId товара на витрине
merchant_order_idЗаказ продавца
client_order_idЗаказ покупателя на витрине; несколько заказов продавца могут быть в одном
location_idСклад или точка продавца на витрине (DBS)
merchant_location_idId склада у продавца при создании точки
market_location_idСклад маркетплейса (FBS, FBO)
polygon_idЗона доставки DBS, привязка к складу
shipment_id / package_idОтгрузка и грузоместо — FBS/FBO, в DBS нет
return_idЗаявка на возврат. Intro DBS: один заказ продавца — одна заявка
cancellation_idЗаявка на отмену (число)

offer_id и product_id в одном запросе

В фильтрах и в загрузке цен, остатков, соответствий и архива:

Заполняется либо offer_id, либо product_id. Если заполнены оба идентификатора, то используется только product_id. Витрина может потребовать передавать оба параметра.

То же в каждой строке product/price/update и product/stock/update. В строке остатка обязательны location_id и count. Артикул и id товара — по правилу выше, оба сразу не обязательны.

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

{
  "items": [
    {
      "offer_id": "PHONE-001",
      "product_id": "PRD-PHONE-01",
      "location_id": "wh-msk-dbs-01",
      "count": 50
    }
  ]
}

Витрина применит product_id. В загрузке цен обязательны currency и items; в каждой строке обязателен price. Цена — целое, значение × 100.

{
  "currency": "RUB",
  "items": [
    {
      "offer_id": "PHONE-001",
      "product_id": "PRD-PHONE-01",
      "price": 5999000
    }
  ]
}

Фильтры списков

Правило общее (как в DBS):

Если поле фильтра не передано, равно null или передан пустой массив [], фильтрация по этому полю не применяется. При одновременном указании нескольких фильтров условия объединяются по AND.

Других связок (OR, NOT) в контракте нет.

Что из этого следует:

  • Поле не передали или null — по нему не фильтруют.
  • Массив [] — тоже не фильтруют.
  • Несколько заполненных полей — все сразу (AND): заказ должен подойти по каждому.
  • Для дат и флагов (since, to, updated_at, is_archived) пустой массив не подходит. Чтобы не фильтровать — не передавать поле или передать null.

В фильтрах цен, остатков и соответствий: если переданы и offer_id, и product_id, берётся только product_id. Это не «верни строки, где совпали оба id».

Сейчас в OpenAPI FBS у списка заказов все поля фильтра и cursor помечены обязательными, у части списков FBO обязательных полей нет, а текст про [] и AND стоит не на всех фильтрах. Это расхождение с DBS, его поправят. Для всех схем действуйте как ниже: обязательны filter и limit, поля внутри filter не обязательны, пустой [] поле выключает.

Что обязательно в списке

В каждом списке ниже обязательны filter и limit. cursor можно не слать.

МетодПо чему можно сузить выборку
/v1/order/dbs/listЗаказы продавца merchant_order_id[], дата создания since / to (RFC3339), статусы status[] (NEW … CANCELLED)
/v1/order/dbs/status/listЗаказы merchant_order_id[], статусы status[], время смены статуса updated_at (RFC3339)
/v1/location/listТочки location_id[], типы location_types[], статусы status[]
/v1/polygon/listСклады location_id[], полигоны polygon_id[], статусы status[]
/v1/cancellation/listЗаявки cancellation_id[], статусы status[]
/v1/return/listСтатусы status[], заявки return_id[], заказы покупателя client_order_id[], заказы продавца merchant_order_id[], период создания created_at (since / to)
/v1/product/price/infooffer_id[], product_id[]
/v1/product/stock/infoАрхив is_archived, склады location_id[], offer_id[], product_id[]
/v1/product/mapping/listАрхив is_archived, offer_id[], product_id[]

Сами поля внутри filter не обязательны. Обязателен сам filter, даже пустой {}.

Первая страница, без сужения:

{
  "filter": {},
  "limit": 100
}

И склад, и статус сразу (AND) — пример для списка локаций, статус ACTIVE:

{
  "filter": {
    "location_id": ["wh-msk-dbs-01"],
    "status": ["ACTIVE"]
  },
  "limit": 100
}

Пустой массив = это поле не участвует:

{
  "filter": {
    "merchant_order_id": [],
    "status": ["NEW", "CONFIRMED"]
  },
  "cursor": "",
  "limit": 100
}

Здесь отбор только по status. merchant_order_id: [] список не сужает. limit: минимум 1, максимум 300, по умолчанию 100.

У заказов FBS в фильтре есть свои поля витрины (market_location_id, период updated_since / updated_to). Это специфика схемы, не другое правило пустого массива. Пример заполненного фильтра:

{
  "filter": {
    "merchant_order_id": ["ORD-FBS-2026-101"],
    "status": ["NEW"],
    "updated_since": "2026-07-02T10:25:00+02:00",
    "updated_to": "2026-07-02T10:25:00+02:00",
    "market_location_id": ["koledino"]
  },
  "cursor": "",
  "limit": 100
}

Рекомендация. Пока OpenAPI FBS не приведён к DBS, витрина может требовать лишние поля. Если пустой filter: {} на списке заказов FBS не проходит — это ожидаемое расхождение, не новое правило фильтра.

Страницы: cursor и limit

cursor — с какой позиции читать дальше. limit — сколько строк на странице.

В ответе списка — массив объектов, плюс часто next_cursor и total. Что обязательно — зависит от метода:

СписокЧто обязательно в ответе
Заказыничего не помечено обязательным
Ценыprices, next_cursor
Остаткиstocks
Локацииlocations
Возвратыreturns
Обновления статусовorder_updates

Про next_cursor сказано только «курсор начала отсчёта». Правила «пустая строка = конец» в контракте нет.

Рекомендация. Пустой или отсутствующий next_cursor считать концом списка. Не ждать total в каждом ответе. Не считать, что курсор «запомнил» фильтр: в контракте этого нет. Если сменить filter и оставить тот же cursor, поведение не описано. Не ставить limit больше 300.

Даты

Дата-время — RFC3339 с часовым поясом. Пример в контракте: 2026-07-02T10:25:00+02:00. Иначе поведение может быть непредсказуемым. В errors это код INVALID_DATE_TIME. Дата без времени — YYYY-MM-DD (INVALID_DATE). Слот доставки — HH:MM.

Деньги, валюта, размер и вес

  • Валюты: RUB, BYN, KZT, EUR, USD, CNY.
  • Цены (price, old_price, min_price) — целые, × 100 (копейки и аналоги).
  • НДС: VAT_0, VAT_5, VAT_7, VAT_10, VAT_22, NO_VAT.
  • Габариты точки: см и кг. При создании обязательны length, width, height, weight.
  • Вес экземпляра в заказе — кг (weight).
  • count остатка — целое, последнее значение, которое загрузил продавец. При обновлении обязательны location_id и count.

Склады и типы доставки (DBS)

Типы точки: WAREHOUSE (склад), PICKUP_POINT (пункт выдачи), CLICK_AND_COLLECT (самовывоз). CLICK_AND_COLLECT — сразу склад и выдача. Отдельный WAREHOUSE для той же точки не нужен.

В FBS у склада продавца тип только WAREHOUSE: продавец сдаёт отгрузку на склад маркетплейса, своей сети ПВЗ в этой схеме нет.

Тип доставки заказа DBS: COURIER, PICKUP_POINT, CLICK_AND_COLLECT, EXPRESS. Для COURIER и EXPRESS нужен полный адрес address_tail. В самом блоке доставки заказа обязательно только поле delivery_type.

На полигоне типы доставки: COURIER, PICKUP_POINT, EXPRESS. CLICK_AND_COLLECT в опциях полигона нет. Не ставить C&C в delivery_types полигона.

Обратная доставка возврата: COURIER, PICKUP_POINT, RUSSIAN_POST. CLICK_AND_COLLECT для возврата не используется.

Код вручения в сценариях DBS — поле handover_codes. В контракте запроса то же поле названо handoverCodes. В каждой строке обязательны merchant_order_id и code. Максимум 200 строк.

Чего не смешивать между схемами

  • В DBS нет отгрузок, грузомест, этикеток FBS/FBO и поставки FBO на склад маркетплейса.
  • FBS — не «работа со складом маркетплейса как со своим складом выдачи покупателю».
  • Допустимые переходы статуса заказа DBS в API не зафиксированы. Таблица в intro — рекомендация, не контракт.