Конфигурация
GET
/v1/webhooksPOST
/v1/webhooksPATCH
/v1/webhooks/{id}DELETE
/v1/webhooks/{id}POST
/v1/webhooks/{id}/testОтвет GET содержит items, endpoint_limit и тариф. Лимиты по умолчанию: dev/free — 1, pro — 3, pro+ — 5; enterprise настраивается отдельно. Запись и тест требуют webhooks:write, чтение — webhooks:read. СтарыйPUT /v1/webhooks оставлен для совместимости и изменяет первый endpoint.
{
"name": "CRM production",
"url": "https://api.example.com/sapportly/hook",
"enabled": true,
"secret": "whsec_...",
"event_types": ["message.received", "message.processed", "conversation.started", "visitor.online", "visitor.offline", "agent.reply", "flow.rule.triggered", "analytics.recorded", "incident.detected", "conversation.escalated", "conversation.assigned", "conversation.transferred", "routing.suggestion", "team.member.joined", "team.invitation.created", "widget.opened", "widget.session_started", "widget.message_sent"]
}await client.webhooks.create({
name: "CRM production",
url: "https://api.example.com/sapportly/hook",
enabled: true,
secret: process.env.SAPPORTLY_WEBHOOK_SECRET!,
event_types: ["message.received", "message.processed"],
});Подпись
import { verifyWebhook } from "@sapportly/sdk/webhooks";
await verifyWebhook(
process.env.SAPPORTLY_WEBHOOK_SECRET ?? process.env.SUPPORTLY_WEBHOOK_SECRET!,
rawBody,
{
timestamp: req.header("X-Sapportly-Timestamp"),
signature: req.header("X-Sapportly-Signature"),
},
);Тело события
POST на ваш URL. Черновики ИИ (ai.draft) сюда не входят — только сокет.
{
"type": "message.received",
"tenant_id": "uuid",
"timestamp": "2026-08-19T10:00:00Z",
"message_id": "uuid",
"delivery": {
"message_id": "uuid",
"source": "webhook",
"delivery_id": "uuid",
"idempotency_key": "shop:ord_1042:cmt_9"
},
"data": {
"metadata": { "event_id": "uuid", "tenant_id": "uuid", "source": "…" },
"kind": "message_received",
"payload": {
"channel": "custom:shop",
"body": "Где заказ?",
"idempotency_key": "shop:ord_1042:cmt_9"
}
}
}Дедуп — верхний message_id (тот же, что в WS и REST). Канал и текст — в data.payload. Для исходящего агента тип agent.reply, payload с channel / body. Список типов задаёте в конфиге; полный набор — в таблице панели и в event_types при POST/PATCH.