Вебхуки для новых лидов

Вебхук отправляет каждый новый лид из ваших чат-каналов, например из чата на сайте, Messenger и Instagram, в другое приложение сразу после того, как лид получен: в вашу CRM, Zapier, Make, n8n или ваш собственный код. KnowStack делает подписанный HTTPS-запрос POST с контактами лида и перепиской на этот момент.

Вебхуки для лидов входят в Business, Enterprise и бесплатный пробный период. Настроить их можно, если ваша роль позволяет управлять пользователями, например Company Admin.

Как добавить вебхук

  1. Скопируйте адрес вебхука в приложении, которое должно получать лиды. Он должен начинаться с https://.
  2. В KnowStack откройте «Настройки», выберите «Интеграции» и перейдите к блоку «Отправка лидов в CRM».
  3. В разделе «Добавить вебхук» впишите в поле «Название» имя, которое легко узнать, вставьте адрес в поле «Адрес вебхука» и нажмите «Добавить вебхук».
  4. Скопируйте появившийся ключ подписи. Он начинается с whsec_ и показывается только один раз. Затем нажмите «Я сохранил ключ».
  5. Откройте меню вебхука и нажмите «Отправить тест». Результат появится сразу, а также в разделе «Журнал отправок».

Отправляются только лиды, полученные после добавления вебхука; более ранние остаются в KnowStack. Можно добавить несколько вебхуков, и каждый новый лид уходит во все активные.

Адрес должен быть публичным: только https, стандартный порт, без имени пользователя и пароля. Адреса в частной или локальной сети отклоняются, в том числе если публичное имя позже начнёт указывать на такую сеть. Перенаправления не выполняются, поэтому вставьте конечный адрес.

Когда отправляются запросы

СобытиеКогдаЧто содержит
lead.createdЧат получает новый лидЛид и переписка на этот момент
lead.updatedИмя, email или телефон появляются позже в том же лидеТекущие данные лида и список changed с новыми полями, без переписки
testВы нажимаете «Отправить тест»Пример лида с id 0 и короткий пример переписки

Сообщения, написанные после создания лида, не отправляются никогда. Запрос lead.updated уходит только после того, как lead.created был принят, и только если поле из пустого стало заполненным.

Заголовки запроса

ЗаголовокЗначение
Content-Typeapplication/json
User-AgentLeadWebhook/1.0
X-Webhook-Eventlead.created, lead.updated или test
X-Webhook-DeliveryИдентификатор отправки. При повторной попытке той же отправки он не меняется, поэтому используйте его, чтобы отсеивать дубликаты
X-Webhook-TimestampВремя подписи в секундах Unix
X-Webhook-Signaturev1= и HMAC-SHA256 в шестнадцатеричном виде от метки времени, точки и исходного тела запроса, вычисленный с вашим ключом подписи

Тело запроса (версия 1)

Тело запроса — JSON в UTF-8. Оно отправляется без переносов строк, а здесь показано отформатированным. Значения в угловых скобках заменяются вашими: название продукта — KnowStack, адрес — тот, по которому вы входите в систему. Запрос lead.created:

{
  "version": 1,
  "event": "lead.created",
  "deliveryId": "4821",
  "occurredAt": "2026-01-15T10:03:12.000Z",
  "lead": {
    "id": 1375,
    "name": "Anna Novak",
    "email": "[email protected]",
    "phone": null,
    "channel": "web_chat",
    "channelLabel": "Website chat",
    "source": "<product name> · Website chat",
    "question": "Do you have availability next week?",
    "firstPageUrl": "https://example.com/pricing",
    "locale": "en",
    "capturedAt": "2026-01-15T10:02:40.000Z",
    "conversationUrl": "https://<your app address>/dashboard/channels/website-chat?conversation=812"
  },
  "transcript": [
    { "from": "customer", "text": "Hi, do you have availability next week?", "at": "2026-01-15T10:00:05.000Z" },
    { "from": "ai", "text": "Yes, we do. Could I take your email so the team can confirm a time?", "at": "2026-01-15T10:00:09.000Z" },
    { "from": "customer", "text": "Sure, [email protected]", "at": "2026-01-15T10:02:40.000Z" }
  ],
  "transcriptIncomplete": false
}
ПолеЗначение
versionВ этом формате всегда 1. Изменение, которое может сломать ваш код, получит новый номер
event, deliveryIdТе же значения, что в заголовках X-Webhook-Event и X-Webhook-Delivery
occurredAtВремя формирования запроса в формате ISO 8601 (UTC)
lead.idИдентификатор лида в KnowStack. В lead.updated приходит тот же идентификатор, так что вы найдёте созданную запись
lead.name, lead.email, lead.phoneКонтактные данные. Любое из полей может быть null
lead.channelГде шёл чат: сейчас web_chat, messenger или instagram. С новыми каналами появятся новые значения, поэтому принимайте любой текст
lead.channelLabel, lead.sourceОтображаемое название канала и готовый источник лида вида "KnowStack · Instagram" на языке того, кто добавил вебхук
lead.questionВопрос, который клиент задал, когда был получен лид, или null
lead.firstPageUrl, lead.localeСтраница, с которой начался чат на сайте, и язык посетителя. Для других каналов обычно null
lead.capturedAtКогда были оставлены контакты
lead.conversationUrlСсылка на переписку в KnowStack для тех, кто может войти в вашу компанию
transcriptПереписка до момента создания лида, от старых сообщений к новым, не больше 500 сообщений. У каждого есть from (customer, ai или team), text и at
transcriptIncompletetrue, если старые сообщения уже удалены по вашим настройкам хранения. У таких сообщений text равен null, а purged равен true

Тело lead.updated содержит те же поля version, event, deliveryId, occurredAt и lead с текущими значениями лида. Вместо переписки в нём есть changed — список полей, заполненных после прошлого запроса, например ["phone"].

Проверка подписи

  1. Прочитайте исходное тело запроса до разбора JSON.
  2. Соедините значение X-Webhook-Timestamp, точку и исходное тело.
  3. Вычислите HMAC-SHA256 этого текста с вашим ключом подписи (полным значением вместе с whsec_) и запишите его в шестнадцатеричном виде.
  4. Сравните v1= с этим значением и заголовок X-Webhook-Signature сравнением за постоянное время.
  5. Отклоните запрос, если метка времени расходится с вашими часами больше чем на 5 минут. Так старый запрос нельзя будет отправить повторно.

Пример для Node.js с Express:

const crypto = require('crypto');
const express = require('express');

const SECRET = process.env.LEAD_WEBHOOK_SECRET; // whsec_...
const app = express();

// Keep the body raw: the signature covers the exact bytes that were sent.
app.post('/leads', express.raw({ type: 'application/json' }), (req, res) => {
  const timestamp = req.get('X-Webhook-Timestamp') || '';
  const received = req.get('X-Webhook-Signature') || '';
  const expected = 'v1=' + crypto
    .createHmac('sha256', SECRET)
    .update(timestamp + '.' + req.body)
    .digest('hex');

  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
  const valid = received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!fresh || !valid) return res.status(401).end();

  const body = JSON.parse(req.body);
  // req.get('X-Webhook-Delivery') identifies the delivery: skip it if you
  // have already handled it.
  console.log(body.event, body.lead.id);
  res.status(204).end();
});

app.listen(3000);

Для проверки кода: ключ whsec_test, метка времени 1761559200 и тело {"a":1} дают подпись v1=ed347bcd87edf5b36afc10e41346740621d7f3c26b13ee1a4cc1eb7cddd0786f.

Ответы и повторные попытки

Ваш ответЧто происходит
2xxДоставлено
408, 429, 5xx, тайм-аут или сетевая ошибкаПовторные попытки с растущими интервалами примерно 24 часа, затем отметка «ошибка». Retry-After в ответе 429 учитывается, но не больше часа
410Вебхук сразу получает статус «Требует внимания»
401, 403 или 404 три раза без успешной доставки между нимиВебхук получает статус «Требует внимания»
Любой другой код, включая перенаправлениеОтметка «ошибка» без повторных попыток

Отвечайте в течение 10 секунд, иначе попытка считается тайм-аутом. Читаются только первые 64 КБ вашего ответа. Сначала ответьте, а долгую обработку выполняйте потом.

Если вебхук требует внимания

Пока у вебхука статус «Требует внимания» или «На паузе», новые лиды ждут в очереди и не теряются. Когда вебхук перестаёт работать, те, кто управляет пользователями, получают одно уведомление в колокольчике, а также в Telegram, если он подключён. Исправьте принимающее приложение или адрес через «Изменить» либо нажмите «Возобновить», если адрес был верным. Отправка продолжится, начиная с лидов, которые ждали.

«Журнал отправок» в меню вебхука показывает последние 50 запросов с результатом и кодом ответа. Нажмите «Повторить» у неудачного, чтобы отправить его ещё раз с тем же идентификатором отправки. На вкладке «Лиды» каждого чат-канала отметка показывает, дошёл ли лид до CRM; для неотправленного лида выберите «Отправить в CRM ещё раз» в меню его строки. Если лиды продолжают не доходить, а вебхук остаётся активным, в его строке появляется «Последние отправки не прошли», а те, кто управляет пользователями, получают уведомление, не чаще раза в день.

Ключ подписи

Если ключ утёк, выберите «Новый ключ подписи» в меню вебхука. Старый ключ сразу перестаёт работать, поэтому сразу же укажите новый в принимающем приложении.

Если ваша компания перейдёт на тариф без вебхуков для лидов, новые лиды не отправляются. Лиды, пришедшие в это время для активного вебхука, пропускаются и сами не отправятся после повышения тарифа; после повышения каждый из них можно отправить через «Отправить в CRM ещё раз». Лиды, ожидающие у приостановленного вебхука или у вебхука со статусом «Требует внимания», остаются в очереди и уйдут, когда вы повысите тариф и возобновите вебхук. Ваши вебхуки остаются в списке, и их по-прежнему можно приостановить или удалить.