Адрес
POST
https://api.perfektpak.ru/v1/receipts
Тот же адрес и в песочнице — режим выбирает ключ: pp_live_… отвечает боевыми данными, pp_test_… — данными песочницы.
Описание метода
Ваша система сообщает нам, что везёт: позиции, количество, признак маркировки. Заявка появляется у нас в статусе
Правила: 1–500 позиций;
Идемпотентность: повтор с тем же
PENDING_CONFIRMATION и не видна складу, пока наш менеджер не нажмёт «Подтвердить» — после этого она становится обычной приёмкой (EXPECTED → RECEIVING → RECEIVED / RECEIVED_WITH_DISCREPANCY). Ответственность за товар возникает с фактической приёмки, не с заявки.Правила: 1–500 позиций;
honest_mark обязателен у каждой позиции и одинаков у всех (склад принимает задание либо целиком по кодам маркировки, либо целиком по штрихкодам — смешанную заявку отклоняем кодом mixed_marking, разделите на две); cabinet_id обязателен, если у вас больше одного кабинета (см. GET /me).Идемпотентность: повтор с тем же
external_ref, пока заявка в PENDING_CONFIRMATION, возвращает её же с кодом 200 — вторая не создаётся. Каждая заявка пишется в неизменяемый журнал (что, когда, каким ключом) — это доказательная база при расхождениях.Авторизация
Authorization: Bearer <ключ>
Ключ выдаёт менеджер (боевой) или песочница (тестовый).
Тело запроса обязательно
Схема: ReceiptDraft
-
cabinet_idстрокаКабинет изGET /me. Необязателен, если кабинет один. -
external_refстрокаВаш номер документа. Вернём как есть; повтор с тем же номером, пока заявка ждёт подтверждения, не создаёт вторую.до 64 симв. -
commentстрокадо 500 симв. -
planned_dateстрокаПлановая дата привоза, ГГГГ-ММ-ДД (МСК). -
itemsмассив обязательно1…500 элементовполя элемента — ReceiptDraftItem
-
barcodeстрока обязательноШтрихкод товара — по нему склад считает единицы. Один штрихкод — одна позиция.до 64 симв. -
nameстрокаНазвание, как его видит кладовщик. Необязательно, если товар нам уже известен. -
articleстрока -
qtyцелое число обязательно1…100000 -
honest_markлогическое обязательноПодлежит маркировке «Честный знак». Обязателен и одинаков у всех позиций одной заявки.
-
Ответы
201 Заявка создана.
Схема: Receipt
-
idстрока обязательно -
numberстрока обязательноНомер приёмки, как он подписан у нас. -
statusстрокаReceiptStatusобязательноСтатус приёмки — привоза товара селлером на склад ПерфектПак.PENDING_CONFIRMATION— заявлена через API из вашей системы и ждёт подтверждения нашим менеджером (склад её ещё не видит);EXPECTED— заявлена, ещё не началась;RECEIVING— идёт пересчёт прямо сейчас;RECEIVED— завершена, количество сошлось;RECEIVED_WITH_DISCREPANCY— завершена, количество не сошлось (см.discrepancy_qtyиitems[].shortage_reason).Значения:PENDING_CONFIRMATIONEXPECTEDRECEIVINGRECEIVEDRECEIVED_WITH_DISCREPANCY -
status_labelстрока обязательно -
expected_qtyцелое число обязательноСколько единиц всего заявлено по накладной. -
accepted_qtyцелое число обязательноСколько единиц всего фактически приняли. -
discrepancy_qtyцелое число обязательноexpected_qtyминусaccepted_qty, никогда не отрицательное.не меньше 0 -
created_atстрока обязательноКогда приёмку завели. RFC 3339, +03:00 (МСК). -
completed_atстрока или null обязательноКогда приёмку закрыли, илиnull, пока она ещё идёт. RFC 3339, +03:00 (МСК). -
sourceстрокаКто заявил товар:api— ваша система через POST /v1/receipts,file— наш менеджер по вашей выгрузке,manual— наш менеджер вручную. Пусто у приёмок, заведённых до v1.1.Значения:apifilemanual -
external_refстрокаВаш номер документа из POST /v1/receipts, как есть. Только уsource: api. -
commentстрока -
planned_dateстрока или nullПлановая дата привоза (полночь МСК) илиnull. -
confirmed_atстрока или nullКогда наш менеджер подтвердил заявку из API;nullдо подтверждения и у приёмок не из API. -
itemsмассивСостав приёмки по SKU. Поле присутствует только в ответеGET /receipts/{id}— в спискеGET /receiptsего нет.поля элемента — ReceiptItem
-
barcodeстрока обязательно -
articleстрокаАртикул продавца. Поле опущено, если у товара нет артикула. -
nameстрока обязательно -
honest_markлогическоеПозиция подлежит маркировке «Честный знак» — каждая единица принимается по коду маркировки, а не по штрихкоду товара. -
expected_qtyцелое число обязательноСколько единиц этого SKU заявлено по накладной. -
accepted_qtyцелое число обязательноСколько единиц этого SKU фактически приняли и посчитали. -
discrepancy_qtyцелое число обязательноexpected_qtyминусaccepted_qty, никогда не отрицательное.не меньше 0 -
shortage_reasonстрокаПричина расхождения по этой позиции, по-русски, из курируемого нами списка (не фиксированный enum — список может пополняться; пример ниже не исчерпывающий). Поле опущено, когда расхождения нет.
-
200
Такая заявка (тот же external_ref) уже ждёт подтверждения — возвращена она.
Схема: Receipt
-
idстрока обязательно -
numberстрока обязательноНомер приёмки, как он подписан у нас. -
statusстрокаReceiptStatusобязательноСтатус приёмки — привоза товара селлером на склад ПерфектПак.PENDING_CONFIRMATION— заявлена через API из вашей системы и ждёт подтверждения нашим менеджером (склад её ещё не видит);EXPECTED— заявлена, ещё не началась;RECEIVING— идёт пересчёт прямо сейчас;RECEIVED— завершена, количество сошлось;RECEIVED_WITH_DISCREPANCY— завершена, количество не сошлось (см.discrepancy_qtyиitems[].shortage_reason).Значения:PENDING_CONFIRMATIONEXPECTEDRECEIVINGRECEIVEDRECEIVED_WITH_DISCREPANCY -
status_labelстрока обязательно -
expected_qtyцелое число обязательноСколько единиц всего заявлено по накладной. -
accepted_qtyцелое число обязательноСколько единиц всего фактически приняли. -
discrepancy_qtyцелое число обязательноexpected_qtyминусaccepted_qty, никогда не отрицательное.не меньше 0 -
created_atстрока обязательноКогда приёмку завели. RFC 3339, +03:00 (МСК). -
completed_atстрока или null обязательноКогда приёмку закрыли, илиnull, пока она ещё идёт. RFC 3339, +03:00 (МСК). -
sourceстрокаКто заявил товар:api— ваша система через POST /v1/receipts,file— наш менеджер по вашей выгрузке,manual— наш менеджер вручную. Пусто у приёмок, заведённых до v1.1.Значения:apifilemanual -
external_refстрокаВаш номер документа из POST /v1/receipts, как есть. Только уsource: api. -
commentстрока -
planned_dateстрока или nullПлановая дата привоза (полночь МСК) илиnull. -
confirmed_atстрока или nullКогда наш менеджер подтвердил заявку из API;nullдо подтверждения и у приёмок не из API. -
itemsмассивСостав приёмки по SKU. Поле присутствует только в ответеGET /receipts/{id}— в спискеGET /receiptsего нет.поля элемента — ReceiptItem
-
barcodeстрока обязательно -
articleстрокаАртикул продавца. Поле опущено, если у товара нет артикула. -
nameстрока обязательно -
honest_markлогическоеПозиция подлежит маркировке «Честный знак» — каждая единица принимается по коду маркировки, а не по штрихкоду товара. -
expected_qtyцелое число обязательноСколько единиц этого SKU заявлено по накладной. -
accepted_qtyцелое число обязательноСколько единиц этого SKU фактически приняли и посчитали. -
discrepancy_qtyцелое число обязательноexpected_qtyминусaccepted_qty, никогда не отрицательное.не меньше 0 -
shortage_reasonстрокаПричина расхождения по этой позиции, по-русски, из курируемого нами списка (не фиксированный enum — список может пополняться; пример ниже не исчерпывающий). Поле опущено, когда расхождения нет.
-
400
Тело не прошло проверку: validation_error (поле — в message), cabinet_required, mixed_marking, bad_request (не JSON или неизвестное поле).
Схема: 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. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-
502
Склад временно не принял заявку (warehouse_unavailable). Заявка не создана — повторите через минуту.
Схема: 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. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-
503
Заявки через API не включены для вашего ключа (write_disabled).
Схема: 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. Присылайте его в поддержку, чтобы нашли конкретный вызов.
-