Адрес
GET
https://api.perfektpak.ru/v1/shipments
Тот же адрес и в песочнице — режим выбирает ключ: pp_live_… отвечает боевыми данными, pp_test_… — данными песочницы.
Описание метода
Отгрузки — то, что мы собрали и передали в маркетплейс (у WB это называется «поставка»; не путать с ресурсом
receipt — привозом товара селлером к нам, см. глоссарий в /docs).Авторизация
Authorization: Bearer <ключ>
Ключ выдаёт менеджер (боевой) или песочница (тестовый).
Параметры запроса
marketplace
в строке запроса
Фильтр по маркетплейсу. Без фильтра — отгрузки во все маркетплейсы.
Значения:
WB OZONПример:
WBstatus
в строке запроса
Фильтр по статусу отгрузки. Без фильтра — отгрузки во всех статусах.
Значения:
ASSEMBLING HANDED_OVER ACCEPTEDПример:
HANDED_OVERcreated_from
в строке запроса
Нижняя граница
created_at, включительно. RFC 3339 со смещением +03:00 (МСК), например 2026-08-01T00:00:00+03:00; также принимается короткая дата ГГГГ-ММ-ДД — она читается как полночь по Москве.created_to
в строке запроса
Верхняя граница
created_at, исключительно. RFC 3339 со смещением +03:00 (МСК), например 2026-08-29T00:00:00+03:00; также принимается короткая дата ГГГГ-ММ-ДД — она читается как полночь по Москве.limit
в строке запроса
Размер страницы. Значение вне диапазона молча округляется до ближайшей границы (0 и меньше — до значения по умолчанию, больше максимума — до максимума); ошибка
400 bad_request — только если значение вообще не целое число.Пример:
50cursor
в строке запроса
Непрозрачный курсор страницы из
next_cursor предыдущего ответа. Не передавайте для первой страницы. Курсор, который мы не выдавали сами, — это 400 bad_cursor, а не тихий возврат к первой странице.Ответы
200 OK
Схема: ShipmentPage
-
itemsмассив обязательнополя элемента — Shipment
-
idстрока обязательно -
marketplaceстрокаMarketplaceобязательноМаркетплейс кабинета.WB— Wildberries,OZON— Ozon.Значения:WBOZON -
external_idстрока обязательноНомер отгрузки в кабинете маркетплейса (у WB это и есть «поставка WB №…»). -
nameстрокаНазвание отгрузки, если ему его давали. Поле опущено, если названия нет. -
statusстрокаShipmentStatusобязательноСтатус отгрузки — партии заказов, которую мы передаём маркетплейсу (у WB в кабинете она называется «поставка»).ASSEMBLING— отгрузка открыта, мы ещё докладываем в неё заказы;HANDED_OVER— закрыта с нашей стороны и передана маркетплейсу;ACCEPTED— маркетплейс отсканировал отгрузку на своём складе или сортировочном центре.Значения:ASSEMBLINGHANDED_OVERACCEPTED -
status_labelстрока обязательно -
orders_countцелое число обязательноЧисло заказов в отгрузке. -
created_atстрока обязательноКогда отгрузку открыли. RFC 3339, +03:00 (МСК). -
closed_atстрока или null обязательноКогда отгрузку закрыли с нашей стороны, илиnull, пока она ещё собирается. RFC 3339, +03:00 (МСК). -
accepted_atстрока или null обязательноМомент, когда маркетплейс отсканировал отгрузку на своём складе или сортировочном центре — юридически значимый факт приёма, илиnull, пока этого не произошло. RFC 3339, +03:00 (МСК). -
ordersмассивЗаказы внутри отгрузки. Поле присутствует только в ответеGET /shipments/{id}— в спискеGET /shipmentsего нет.поля элемента — Order
-
idстрока обязательно -
marketplaceстрокаMarketplaceобязательноМаркетплейс кабинета.WB— Wildberries,OZON— Ozon.Значения:WBOZON -
external_idстрока обязательноНомер, под которым заказ виден в вашем кабинете маркетплейса (сборочное задание WB, отправление Ozon) — сверяйте с ним глазами. -
statusстрокаOrderStatusобязательноНормализованный статус заказа, единый для WB и Ozon. Набор закрытый и исчерпывающий: любой заказ попадает ровно в одно значение,OTHER— предохранитель на случай статуса маркетплейса, которого ещё нет в нашей нормализации (заказ не теряется, а виден с этим статусом).NEW— маркетплейс завёл заказ, в наши отгрузки он ещё не попал;ASSEMBLING— уже в отгрузке, отгрузка не закрыта;IN_DELIVERY— отгрузка передана маркетплейсу;COMPLETED— заказ доехал до покупателя;CANCELLED— отменён любой из сторон.Значения:NEWASSEMBLINGIN_DELIVERYCOMPLETEDCANCELLEDOTHER -
status_labelстрока обязательноЧеловекочитаемая подпись статуса на русском. Формулировка может меняться без анонса — ветвитесь в коде поstatus, не по этой строке. -
marketplace_statusобъектMarketplaceStatusобязательноСырая пара статусов маркетплейса, как есть, без нормализации — по ней служба поддержки селлера спорит с маркетплейсом. Для логики используйте нормализованныйOrder.status, а не эти значения: набор сырых статусов не закрыт и различается между WB и Ozon.поля MarketplaceStatus
-
supplierстрокаСтатус поставщика как есть у маркетплейса (WB —supplier_status, Ozon —status). Поле опущено, если маркетплейс его не прислал. -
buyerстрокаСтатус покупателя как есть у маркетплейса (WB —wb_status, Ozon —substatus). Поле опущено, если маркетплейс его не прислал. -
changed_atстрокаКогда эта пара статусов последний раз менялась, по нашим наблюдениям. Поле опущено, если неизвестно. RFC 3339, +03:00 (МСК).
-
-
articleстрокаАртикул продавца. Поле опущено, если у товара нет артикула. -
barcodeстрокаШтрихкод товара в заказе. Поле опущено, если неизвестен. -
nm_idцелое числоАртикул WB (nmId). Поле опущено для заказов Ozon и когда номенклатура WB неизвестна. -
is_b2bлогическое обязательноЗаказ из B2B-поставки (опт для сетей), а не обычный розничный FBS-заказ. -
shipment_idстрока или null обязательноИдентификатор нашей отгрузки (idизGET /shipments), в которую попал заказ, илиnull, пока заказ ни в одну отгрузку не добавлен. -
shipment_external_idстрока или null обязательноНомер той же отгрузки в кабинете маркетплейса, илиnullпо той же причине, что иshipment_id. -
created_atстрока обязательноКогда маркетплейс создал заказ. RFC 3339, +03:00 (МСК). -
packed_atстрока или null обязательноКогда мы закончили собирать заказ, илиnull, пока сборка не завершена. RFC 3339, +03:00 (МСК). -
synced_atстрока или null обязательноКогда мы последний раз обновили состояние заказа из маркетплейса, илиnull, если ни разу. RFC 3339, +03:00 (МСК).
-
-
-
totalцелое число обязательно -
next_cursorстрока или null обязательноКурсор следующей страницы для параметраcursor, илиnull, если это последняя страница.
400 Параметры запроса не прошли валидацию, либо курсор пагинации не наш или испорчен.
Схема: ErrorResponse
-
errorобъектErrorобязательнополя Error
-
codeстрокаErrorCodeобязательноМашинный, стабильный код ошибки — ветвитесь в коде по нему, а не по текстуmessage(он на русском и может измениться).unauthorized— ключ не передан или не существует;key_revoked— ключ существует, но отозван;bad_request— параметры запроса не прошли валидацию;bad_cursor— курсор не наш или испорчен (в отличие от обычногоbad_request, здесь нужно перезапросить страницу заново, а не повторять тот же курсор);not_found— ресурса нет либо он принадлежит не вашему client_id (специально неразличимо);rate_limited— превышен лимит запросов;internal— ошибка на нашей стороне. С v1.1:validation_error— поле тела запроса не прошло проверку (поле названо вmessage);cabinet_required— у вас несколько кабинетов, укажитеcabinet_id;mixed_marking— в одной заявке позиции и с маркировкой, и без, разделите на две;write_disabled— заявки через API ещё не включены для вашего ключа;warehouse_unavailable— склад временно не принял заявку, повторите через минуту (заявка не создана);webhook_url_unverified— адрес не ответил 2xx на проверочное событие;webhook_limit— больше 10 подписок;webhooks_unavailable— вебхуки временно выключены;sandbox_only— операция только для тестового ключа.Значения:unauthorizedkey_revokedrate_limitednot_foundbad_requestbad_cursorinternalvalidation_errorcabinet_requiredmixed_markingwrite_disabledwarehouse_unavailablewebhook_url_unverifiedwebhook_limitwebhooks_unavailablesandbox_only -
messageстрока обязательноТекст ошибки на русском для лога и для человека — не для ветвления в коде. -
request_idстрока обязательноТот же идентификатор, что и в заголовкеX-Request-Id. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-
401
Ключ не передан или не существует (unauthorized), либо существует, но отозван (key_revoked). Этот ответ единственный, где нет заголовков X-RateLimit-* — они появляются только после того, как ключ прошёл проверку.
Схема: ErrorResponse
-
errorобъектErrorобязательнополя Error
-
codeстрокаErrorCodeобязательноМашинный, стабильный код ошибки — ветвитесь в коде по нему, а не по текстуmessage(он на русском и может измениться).unauthorized— ключ не передан или не существует;key_revoked— ключ существует, но отозван;bad_request— параметры запроса не прошли валидацию;bad_cursor— курсор не наш или испорчен (в отличие от обычногоbad_request, здесь нужно перезапросить страницу заново, а не повторять тот же курсор);not_found— ресурса нет либо он принадлежит не вашему client_id (специально неразличимо);rate_limited— превышен лимит запросов;internal— ошибка на нашей стороне. С v1.1:validation_error— поле тела запроса не прошло проверку (поле названо вmessage);cabinet_required— у вас несколько кабинетов, укажитеcabinet_id;mixed_marking— в одной заявке позиции и с маркировкой, и без, разделите на две;write_disabled— заявки через API ещё не включены для вашего ключа;warehouse_unavailable— склад временно не принял заявку, повторите через минуту (заявка не создана);webhook_url_unverified— адрес не ответил 2xx на проверочное событие;webhook_limit— больше 10 подписок;webhooks_unavailable— вебхуки временно выключены;sandbox_only— операция только для тестового ключа.Значения:unauthorizedkey_revokedrate_limitednot_foundbad_requestbad_cursorinternalvalidation_errorcabinet_requiredmixed_markingwrite_disabledwarehouse_unavailablewebhook_url_unverifiedwebhook_limitwebhooks_unavailablesandbox_only -
messageстрока обязательноТекст ошибки на русском для лога и для человека — не для ветвления в коде. -
request_idстрока обязательноТот же идентификатор, что и в заголовкеX-Request-Id. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-
429 Превышен лимит запросов — 60 в минуту на ключ, с всплеском до 20.
Схема: ErrorResponse
-
errorобъектErrorобязательнополя Error
-
codeстрокаErrorCodeобязательноМашинный, стабильный код ошибки — ветвитесь в коде по нему, а не по текстуmessage(он на русском и может измениться).unauthorized— ключ не передан или не существует;key_revoked— ключ существует, но отозван;bad_request— параметры запроса не прошли валидацию;bad_cursor— курсор не наш или испорчен (в отличие от обычногоbad_request, здесь нужно перезапросить страницу заново, а не повторять тот же курсор);not_found— ресурса нет либо он принадлежит не вашему client_id (специально неразличимо);rate_limited— превышен лимит запросов;internal— ошибка на нашей стороне. С v1.1:validation_error— поле тела запроса не прошло проверку (поле названо вmessage);cabinet_required— у вас несколько кабинетов, укажитеcabinet_id;mixed_marking— в одной заявке позиции и с маркировкой, и без, разделите на две;write_disabled— заявки через API ещё не включены для вашего ключа;warehouse_unavailable— склад временно не принял заявку, повторите через минуту (заявка не создана);webhook_url_unverified— адрес не ответил 2xx на проверочное событие;webhook_limit— больше 10 подписок;webhooks_unavailable— вебхуки временно выключены;sandbox_only— операция только для тестового ключа.Значения:unauthorizedkey_revokedrate_limitednot_foundbad_requestbad_cursorinternalvalidation_errorcabinet_requiredmixed_markingwrite_disabledwarehouse_unavailablewebhook_url_unverifiedwebhook_limitwebhooks_unavailablesandbox_only -
messageстрока обязательноТекст ошибки на русском для лога и для человека — не для ветвления в коде. -
request_idстрока обязательноТот же идентификатор, что и в заголовкеX-Request-Id. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-
500 Ошибка на нашей стороне. request_id стоит передать в поддержку.
Схема: ErrorResponse
-
errorобъектErrorобязательнополя Error
-
codeстрокаErrorCodeобязательноМашинный, стабильный код ошибки — ветвитесь в коде по нему, а не по текстуmessage(он на русском и может измениться).unauthorized— ключ не передан или не существует;key_revoked— ключ существует, но отозван;bad_request— параметры запроса не прошли валидацию;bad_cursor— курсор не наш или испорчен (в отличие от обычногоbad_request, здесь нужно перезапросить страницу заново, а не повторять тот же курсор);not_found— ресурса нет либо он принадлежит не вашему client_id (специально неразличимо);rate_limited— превышен лимит запросов;internal— ошибка на нашей стороне. С v1.1:validation_error— поле тела запроса не прошло проверку (поле названо вmessage);cabinet_required— у вас несколько кабинетов, укажитеcabinet_id;mixed_marking— в одной заявке позиции и с маркировкой, и без, разделите на две;write_disabled— заявки через API ещё не включены для вашего ключа;warehouse_unavailable— склад временно не принял заявку, повторите через минуту (заявка не создана);webhook_url_unverified— адрес не ответил 2xx на проверочное событие;webhook_limit— больше 10 подписок;webhooks_unavailable— вебхуки временно выключены;sandbox_only— операция только для тестового ключа.Значения:unauthorizedkey_revokedrate_limitednot_foundbad_requestbad_cursorinternalvalidation_errorcabinet_requiredmixed_markingwrite_disabledwarehouse_unavailablewebhook_url_unverifiedwebhook_limitwebhooks_unavailablesandbox_only -
messageстрока обязательноТекст ошибки на русском для лога и для человека — не для ветвления в коде. -
request_idстрока обязательноТот же идентификатор, что и в заголовкеX-Request-Id. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-