Исходящие webhook-события
Исходящий webhook отправляет внешней системе уведомление о выбранном изменении опубликованной бизнес-сущности. Подписка принадлежит конкретному API-ключу и работает только в пределах ресурсов, доступных этому ключу.
Получить доступный каталог
Каталог событий формируется с учётом scopes текущего ключа:
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 домена выбранного события.
Подписка доступна только ключу, которым создана. Другой ключ того же портала не может получить, изменить или протестировать её по идентификатору.
Эндпоинты
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Все запросы передают:
X-API-Key: spk_...Создать подписку
Один элемент массива создаёт одну подписку на одно событие и один публичный HTTPS endpoint:
POST /api/v1/integration-api/webhook
X-API-Key: spk_...
Content-Type: application/json[
{
"name": "Изменение статуса заявки",
"event": "integration_api.procurement.status_changed",
"url": "https://example.com/webhooks/procurements",
"isActive": true
}
]Успешный create-response:
{
"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 возвращается только один раз в ответе создания. Сохраните его в защищённом хранилище.
Получить подписки
GET /api/v1/integration-api/webhook
X-API-Key: spk_...{
"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"
}
]
}Ответ списка не содержит секрет подписи.
Изменить подписку
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 нового домена.
Проверить доставку
POST /api/v1/integration-api/webhook/hook_id/test
X-API-Key: spk_...Запрос отправляет integration.test_event на URL подписки. Тест использует те же заголовки и HMAC-подпись, что и бизнес-события, и не возвращает секрет.
Payload v1.0
Тело webhook содержит только стабильные идентификаторы события и сущности, версию ресурса и время:
{
"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-подпись
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:
{timestamp}.{requestBody}Получатель должен вычислить HMAC-SHA256 с сохранённым секретом, сравнить подпись безопасным способом и только после этого обрабатывать JSON.
Жизненный цикл доступа
Перед каждой доставкой проверяются API-ключ и его актуальные scopes. Новые доставки по подписке прекращаются, если:
- ключ отозван;
- срок действия ключа истёк;
- утрачен
webhooks.write; - утрачен read-scope домена события.
Возврат ранее утраченного scope не расширяет контракт: подписка продолжает работать только для события, разрешённого актуальным каталогом meta.
Повторы доставки
SNABZHENETS+ может повторить доставку при сетевой ошибке, 408, 429 или ответе 5xx. Получатель должен сохранять обработанные eventId и возвращать успешный HTTP-статус для уже принятого события, не применяя его повторно.