Перейти к содержимому

Вебхук: формат и подпись

Вебхук — POST на ваш адрес на каждое новое событие источника, на который он подписан. Как настроить — Получать события вебхуком.

{
"id": 512,
"type": "event.received",
"created_at": "2026-10-19T13:30:05Z",
"source": {"id": 14, "name": "Заявки с лендинга"},
"data": {"id": 512, "source": {"id": 14, "name": "Заявки с лендинга"}, "channel": "webhook", "received_at": "2026-10-19T13:30:00Z", "payload": {"name": "Анна"}, "repeat_of": null, "history": false, "deleted_at": null}
}
  • id — номер доставки;
  • type — event.received; проверка связи кнопкой «Тест» шлёт {"type": "ping"};
  • data — то же событие, что отдаёт лента GET /api/v1/events (API: правила).

Запросов не шлют: повторная отправка, пустое событие, удалённое событие, загрузка файла, первый запуск опроса и события, принятые до подписки.

Заголовок Что в нём
X-Goodwink-Event тип: event.received или ping
X-Goodwink-Delivery номер доставки
X-Goodwink-Signature t=<unix-время>,v1=<hex>

v1 = HMAC-SHA256(секрет, t + "." + тело как есть), в шестнадцатеричном виде. Секрет — в карточке вебхука на вкладке «Интеграции», кнопка «Показать».

Проверяйте подпись по сырым байтам тела до разбора JSON и отбрасывайте запросы, у которых t старше нескольких минут.

import hashlib
import hmac
def signed(body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
want = hmac.new(secret.encode(), f"{parts['t']}.".encode() + body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(want, parts["v1"])
  • Ответ 2xx — доставлено. Любой другой ответ или нет ответа — повтор с растущим интервалом: 30 секунд, минута, две… до суток.
  • Гарантия — «хотя бы раз»: доставка с тем же id может прийти повторно, приём должен это пережить.
  • Адрес — только публичный http(s); он проверяется при сохранении и перед каждой отправкой, запрос идёт ровно на проверенный адрес.
  • Журнал попыток — в карточке вебхука.