Skip to content

Исходящие webhook-события

Исходящий webhook отправляет внешней системе уведомление о выбранном изменении опубликованной бизнес-сущности. Подписка принадлежит конкретному API-ключу и работает только в пределах ресурсов, доступных этому ключу.

Получить доступный каталог

Каталог событий формируется с учётом scopes текущего ключа:

http
GET /api/v1/integration-api/meta
X-API-Key: spk_...

Используйте только имена из поля events. Пустой список не означает подписку на все события. integration.test_event отправляется только явным тестовым запросом и не используется как бизнес-событие.

События v1.0

СущностьEventЧто означаетОбязательный read-scope
Заявкаintegration_api.procurement.createdСоздана заявкаpurchase_requisitions.read
Заявкаintegration_api.procurement.updatedИзменены опубликованные поля заявкиpurchase_requisitions.read
Заявкаintegration_api.procurement.stage_changedИзменён этап доступного ключу процессаpurchase_requisitions.read
Заявкаintegration_api.procurement.status_changedИзменён доступный внешней системе статусpurchase_requisitions.read
Номенклатураintegration_api.catalog_item.createdСоздана позицияcatalog.read
Номенклатураintegration_api.catalog_item.updatedИзменены опубликованные поля позицииcatalog.read
Контрагентintegration_api.counterparty.createdСоздан контрагентcounterparties.read
Контрагентintegration_api.counterparty.updatedИзменены опубликованные поля контрагентаcounterparties.read
Контрагентintegration_api.counterparty.status_changedИзменён доступный внешней системе статусcounterparties.read
Складintegration_api.warehouse.createdСоздан складwarehouses.read
Складintegration_api.warehouse.updatedИзменены опубликованные поля складаwarehouses.read
Прайс-листintegration_api.price_list.createdСоздан прайс-листprice_lists.read
Прайс-листintegration_api.price_list.updatedИзменены опубликованные поля прайс-листаprice_lists.read
Прайс-листintegration_api.price_list.status_changedИзменён доступный внешней системе статусprice_lists.read
Входящий счётintegration_api.invoice.createdСоздан счётfinance.read
Входящий счётintegration_api.invoice.updatedИзменены опубликованные поля счётаfinance.read
Входящий счётintegration_api.invoice.status_changedИзменён доступный внешней системе статусfinance.read
Документintegration_api.document_generation.completedГенерация документа завершенаdocuments.read
Документintegration_api.document_generation.failedГенерация документа завершилась ошибкойdocuments.read
Рейсintegration_api.delivery_trip.createdСоздан рейсdelivery_trips.read или logistics.read
Рейсintegration_api.delivery_trip.updatedИзменены опубликованные поля рейсаdelivery_trips.read или logistics.read
Рейсintegration_api.delivery_trip.status_changedИзменён статус рейсаdelivery_trips.read или logistics.read
Остановка рейсаintegration_api.delivery_trip.stop_status_changedИзменён статус остановкиdelivery_trips.read или logistics.read

Фактический массив events из meta имеет приоритет: событие недоступно, если у текущего ключа нет соответствующего read-scope.

Права и владение

Для просмотра подписок нужен webhooks.read. Для создания, изменения и тестовой доставки одновременно требуются:

  • webhooks.write;
  • read-scope домена выбранного события.

Подписка доступна только ключу, которым создана. Другой ключ того же портала не может получить, изменить или протестировать её по идентификатору.

Эндпоинты

http
GET  /api/v1/integration-api/webhook
POST /api/v1/integration-api/webhook
PUT  /api/v1/integration-api/webhook/:id
POST /api/v1/integration-api/webhook/:id/test

Все запросы передают:

http
X-API-Key: spk_...

Создать подписку

Один элемент массива создаёт одну подписку на одно событие и один публичный HTTPS endpoint:

http
POST /api/v1/integration-api/webhook
X-API-Key: spk_...
Content-Type: application/json
json
[
  {
    "name": "Изменение статуса заявки",
    "event": "integration_api.procurement.status_changed",
    "url": "https://example.com/webhooks/procurements",
    "isActive": true
  }
]

Успешный create-response:

json
{
  "items": [
    {
      "id": "hook_id",
      "name": "Изменение статуса заявки",
      "event": "integration_api.procurement.status_changed",
      "url": "https://example.com/webhooks/procurements",
      "isActive": true,
      "createdAt": "2026-07-28T09:00:00.000Z",
      "updatedAt": "2026-07-28T09:00:00.000Z",
      "secretPlaintext": "one-time-secret"
    }
  ]
}

secretPlaintext возвращается только один раз в ответе создания. Сохраните его в защищённом хранилище.

Получить подписки

http
GET /api/v1/integration-api/webhook
X-API-Key: spk_...
json
{
  "items": [
    {
      "id": "hook_id",
      "name": "Изменение статуса заявки",
      "event": "integration_api.procurement.status_changed",
      "url": "https://example.com/webhooks/procurements",
      "isActive": true,
      "successCount": 12,
      "failureCount": 1,
      "lastDeliveredAt": "2026-07-28T10:00:00.000Z",
      "lastErrorAt": null,
      "createdAt": "2026-07-28T09:00:00.000Z",
      "updatedAt": "2026-07-28T09:00:00.000Z"
    }
  ]
}

Ответ списка не содержит секрет подписи.

Изменить подписку

http
PUT /api/v1/integration-api/webhook/hook_id
X-API-Key: spk_...
Content-Type: application/json

{
  "name": "Обновления заявки",
  "event": "integration_api.procurement.updated",
  "url": "https://example.com/webhooks/procurements-v2",
  "isActive": true
}

Ответ возвращает { "item": ... } без секрета подписи. Если событие изменено, сервер повторно проверяет read-scope нового домена.

Проверить доставку

http
POST /api/v1/integration-api/webhook/hook_id/test
X-API-Key: spk_...

Запрос отправляет integration.test_event на URL подписки. Тест использует те же заголовки и HMAC-подпись, что и бизнес-события, и не возвращает секрет.

Payload v1.0

Тело webhook содержит только стабильные идентификаторы события и сущности, версию ресурса и время:

json
{
  "event": "integration_api.procurement.status_changed",
  "eventId": "event-uuid",
  "schemaVersion": "1.0",
  "occurredAt": "2026-07-28T10:00:00.000Z",
  "resource": {
    "type": "procurement",
    "id": "entity-uuid",
    "version": 7
  }
}

eventId — ключ идемпотентности доставки. resource.version помогает обрабатывать изменения одной сущности по порядку. Актуальные подробности получатель запрашивает по resource.id через соответствующий scoped GET тем же API-ключом.

Дополнительные служебные поля, произвольные исходные данные, постоянные ссылки на файлы, бизнес-снимки и связи внешних идентификаторов не передаются.

Заголовки и HMAC-подпись

http
X-Snabplus-Event: integration_api.procurement.status_changed
X-Snabplus-Event-Id: event-uuid
X-Snabplus-Timestamp: 1785232800000
X-Snabplus-Signature: sha256=<hex>

Подпись вычисляется по строке из timestamp и точных байтов HTTP body:

text
{timestamp}.{requestBody}

Получатель должен вычислить HMAC-SHA256 с сохранённым секретом, сравнить подпись безопасным способом и только после этого обрабатывать JSON.

Жизненный цикл доступа

Перед каждой доставкой проверяются API-ключ и его актуальные scopes. Новые доставки по подписке прекращаются, если:

  • ключ отозван;
  • срок действия ключа истёк;
  • утрачен webhooks.write;
  • утрачен read-scope домена события.

Возврат ранее утраченного scope не расширяет контракт: подписка продолжает работать только для события, разрешённого актуальным каталогом meta.

Повторы доставки

SNABZHENETS+ может повторить доставку при сетевой ошибке, 408, 429 или ответе 5xx. Получатель должен сохранять обработанные eventId и возвращать успешный HTTP-статус для уже принятого события, не применяя его повторно.

Связанные страницы

Документация платформы SNABZHENETS+.