ПерфектПак · API v1.1
openapi.yaml ↗
Справочник методов / Агрегированные метрики за период

Метрики за период

GET /metrics
Адрес
GET https://api.perfektpak.ru/v1/metrics

Тот же адрес и в песочнице — режим выбирает ключ: pp_live_… отвечает боевыми данными, pp_test_…данными песочницы.

Описание метода

Один запрос — четыре блока для дашборда: цепочка владельца (funnel), хранение (storage), приёмка (receiving) и отгрузка (shipments). Формулы те же, что использует личный кабинет селлера — цифра обязана совпадать. from и to необязательны: если не передать ни одного, период — последние 30 дней до текущего момента; если передать только один, второй достраивается 30-дневным окном от него. from обязан быть раньше to, а сам период — не длиннее 366 дней; иначе 400 bad_request.

Авторизация

Authorization: Bearer <ключ> Ключ выдаёт менеджер (боевой) или песочница (тестовый).

Параметры запроса

from в строке запроса
строка
Начало периода, включительно. RFC 3339 со смещением +03:00 (МСК), например 2026-08-01T00:00:00+03:00; также принимается короткая дата ГГГГ-ММ-ДД (полночь по Москве). Без параметра — 30 дней до to (или до текущего момента, если to тоже не передан).
to в строке запроса
строка
Конец периода, исключительно. RFC 3339 со смещением +03:00 (МСК), например 2026-08-29T00:00:00+03:00; также принимается короткая дата ГГГГ-ММ-ДД (полночь по Москве). Без параметра — текущий момент (или from + 30 дней, если from передан).

Ответы

200 OK

Схема: Metrics

  • period объект MetricsPeriod обязательно
    поля MetricsPeriod
    • from строка обязательно
      Начало периода, включительно. RFC 3339, +03:00 (МСК).
    • to строка обязательно
      Конец периода, исключительно. RFC 3339, +03:00 (МСК).
  • funnel объект MetricsFunnel обязательно
    Цепочка владельца: принято → на хранении → отгружено → отсортировано маркетплейсом → доставлено покупателю.
    поля MetricsFunnel
    • accepted целое число обязательно
      Единиц принято по приёмкам за период.
    • in_storage целое число обязательно
      Вычисляемый остаток хранения прямо сейчас (принято минус отгружено минус списано) — это моментальный снимок, а не сумма за период. Должен совпадать с суммой quantity по GET /stock.
    • shipped целое число обязательно
      Единиц в отгрузках, закрытых за период (по closed_at).
    • sorted_by_marketplace целое число обязательно
      Заказов за период со статусом маркетплейса из набора: отсортирован маркетплейсом, прибыл в пункт выдачи, получен покупателем, либо отменён покупателем уже при получении.
    • delivered целое число обязательно
      Заказов за период, строго полученных покупателем.
    • by_current_status логическое обязательно
      true, пока история переходов статусов не накоплена — тогда sorted_by_marketplace и delivered посчитаны по текущему статусу заказа на момент запроса, а не по факту попадания в статус внутри периода from/to.
  • storage объект MetricsStorage обязательно
    поля MetricsStorage
    • units целое число обязательно
      Остаток на хранении сейчас, в штуках (моментальный снимок).
    • boxes целое число обязательно
    • pallets целое число обязательно
    • sku_count целое число обязательно
      Число уникальных SKU на хранении сейчас.
    • in_question целое число обязательно
      Единицы под вопросом сейчас (уже включены в units).
    • received целое число обязательно
      Единиц принято за период.
    • shipped целое число обязательно
      Единиц отгружено за период.
  • receiving объект MetricsReceiving обязательно
    поля MetricsReceiving
    • receipts целое число обязательно
      Число приёмок за период.
    • expected_units целое число обязательно
    • accepted_units целое число обязательно
    • fill_rate число обязательно
      accepted_units / expected_units, от 0 до 1. Равен 0, если за период ничего не ожидалось.
      0…1
    • discrepancy_units целое число обязательно
    • shortages_by_reason массив обязательно
      Расхождения за период по причинам.
      поля элемента — ReasonCount
      • reason строка обязательно
        Машинный код причины из курируемого списка (не фиксированный enum — значения могут добавляться).
      • label строка обязательно
      • count целое число обязательно
  • shipments объект MetricsShipments обязательно
    поля MetricsShipments
    • orders_total целое число обязательно
      Всего заказов за период.
    • orders_by_status массив обязательно
      Разбивка orders_total по значениям OrderStatus. Сумма count по всем элементам всегда равна orders_total — набор статусов исчерпывающий по построению.
      поля элемента — StatusCount
      • status строка обязательно
        Одно из значений соответствующего статус-перечисления (здесь — OrderStatus).
      • label строка обязательно
      • count целое число обязательно
    • shipments_closed целое число обязательно
      Число отгрузок, закрытых за период.
    • units_shipped целое число обязательно
    • cancelled целое число обязательно
      Заказов за период со статусом CANCELLED.
    • not_found целое число обязательно
      Единиц, которые сборщик не нашёл при подборе за период.
    • not_found_by_reason массив обязательно
      Расшифровка not_found по причинам.
      поля элемента — ReasonCount
      • reason строка обязательно
        Машинный код причины из курируемого списка (не фиксированный enum — значения могут добавляться).
      • label строка обязательно
      • count целое число обязательно
  • notes массив обязательно
    Оговорки к цифрам выше на русском, рассчитанные на то, чтобы дойти до человека (например, как считаются sorted_by_marketplace и delivered, пока не накоплена история статусов). Пустой массив, если оговорок нет.
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 — операция только для тестового ключа.
      Значения: unauthorized key_revoked rate_limited not_found bad_request bad_cursor internal validation_error cabinet_required mixed_marking write_disabled warehouse_unavailable webhook_url_unverified webhook_limit webhooks_unavailable sandbox_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 — операция только для тестового ключа.
      Значения: unauthorized key_revoked rate_limited not_found bad_request bad_cursor internal validation_error cabinet_required mixed_marking write_disabled warehouse_unavailable webhook_url_unverified webhook_limit webhooks_unavailable sandbox_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 — операция только для тестового ключа.
      Значения: unauthorized key_revoked rate_limited not_found bad_request bad_cursor internal validation_error cabinet_required mixed_marking write_disabled warehouse_unavailable webhook_url_unverified webhook_limit webhooks_unavailable sandbox_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 — операция только для тестового ключа.
      Значения: unauthorized key_revoked rate_limited not_found bad_request bad_cursor internal validation_error cabinet_required mixed_marking write_disabled warehouse_unavailable webhook_url_unverified webhook_limit webhooks_unavailable sandbox_only
    • message строка обязательно
      Текст ошибки на русском для лога и для человека — не для ветвления в коде.
    • request_id строка обязательно
      Тот же идентификатор, что и в заголовке X-Request-Id. Присылайте его в поддержку, чтобы нашли конкретный вызов.