ПерфектПак · API v1.1
openapi.yaml ↗

Ошибки

Единый конверт на всё: {"error": {"code", "message", "request_id"}}. code — машинный и стабильный, ветвитесь в коде по нему; message — по-русски для человека и может меняться без анонса; request_id совпадает с заголовком X-Request-Id — присылайте его в поддержку.

{ "error": { "code": "key_revoked", "message": "Ключ отозван 14.08.2026.", "request_id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890" } }

Коды ошибок

HTTPcodeЧто значитЧто делать
401 unauthorized Ключ не передан ни в одном из двух заголовков, либо такого ключа не существует. Передайте ключ в "Authorization: Bearer <ключ>" или "X-Api-Key". Проверьте, что ключ скопирован целиком.
401 key_revoked Ключ существует, но отозван. Попросите менеджера ПерфектПак выпустить новый ключ для этой интеграции.
429 rate_limited Превышен лимит запросов: 60 в минуту на ключ, всплеск 20. Подождите время из заголовка Retry-After и повторите. Для регулярного опроса ориентируйтесь на средний темп 60/мин, а не на всплеск.
404 not_found Объекта с таким идентификатором нет — либо он есть, но принадлежит не вашему client_id (эти два случая неразличимы намеренно). Проверьте идентификатор. Если уверены, что объект должен существовать и быть вашим, напишите в поддержку с request_id.
400 bad_request Параметр запроса не прошёл валидацию: нечисловой limit, недопустимое значение перечисления, нераспознанная дата, некорректный период from/to. Текст message называет конкретный параметр и допустимые значения — исправьте запрос по нему.
400 bad_cursor Параметр cursor не наш или испорчен. Запросите первую страницу заново без параметра cursor. Не пытайтесь исправить или собрать курсор самостоятельно.
500 internal Ошибка на нашей стороне. Повторите запрос; если повторяется — напишите в поддержку с request_id из тела ответа или заголовка X-Request-Id.
400 validation_error Поле тела запроса не прошло валидацию (например, POST /v1/receipts: пустой items, qty вне диапазона 1…100000, отсутствует barcode). Текст message называет конкретное поле — исправьте тело запроса по нему.
400 cabinet_required У клиента больше одного кабинета маркетплейса, а cabinet_id в запросе не передан. Передайте cabinet_id — идентификатор нужного кабинета из GET /v1/me.
400 mixed_marking В одной заявке POST /v1/receipts перемешаны позиции с honest_mark:true и honest_mark:false — склад принимает задание только целиком по кодам маркировки либо целиком по штрихкодам. Разделите заявку на две — по одной на каждое значение honest_mark.
503 write_disabled Заявки через API (POST /v1/receipts) ещё не включены для вашего ключа. Обратитесь к менеджеру ПерфектПак, чтобы включить приём заявок через API для вашего ключа.
502 warehouse_unavailable Склад временно не принял заявку. Заявка не создана. Повторите запрос через минуту — это временный сбой, а не ошибка в теле запроса.
400 webhook_url_unverified При регистрации вебхука URL не ответил 2xx на webhook.ping за 10 секунд. Проверьте, что URL общедоступен, отвечает 2xx и укладывается в 10 секунд, затем повторите регистрацию.
400 webhook_limit У клиента уже 10 подписок — максимум на клиента. Удалите неиспользуемую подписку (DELETE /v1/webhooks/{id}) или переиспользуйте существующую.
503 webhooks_unavailable Вебхуки временно выключены на нашей стороне. Повторите позже; события за это время не теряются — доставка возобновится, когда вебхуки снова заработают.
403 sandbox_only Операция доступна только тестовому ключу (pp_test_), а запрос пришёл с боевым ключом (pp_live_). Используйте тестовый ключ песочницы для песочничных операций (например, POST /v1/sandbox/reset) — они не действуют на боевые ключи.

Почему 404, а не 403, если объект не мой

Осознанное решение об изоляции. Если бы «объект существует, но не ваш» отвечало 403, а «объекта нет вовсе» — 404, по разнице кодов можно было бы перебором выяснять, какие идентификаторы вообще существуют у других селлеров. Поэтому оба случая отвечают одинаково — 404 not_found.

Заголовки лимита запросов

ЗаголовокСмысл
X-RateLimit-LimitЁмкость всплеска — 20. Не то же самое, что средний лимит 60 в минуту.
X-RateLimit-RemainingСколько запросов из текущего всплеска ещё доступно.
X-RateLimit-ResetUnix-время полного восстановления всплеска.
Retry-AfterТолько на 429: через сколько секунд имеет смысл повторить.

Заголовки X-RateLimit-* есть на любом ответе /v1/*, кроме 401 — ключ ещё не проверен, лимит считать не по чему.