Вебхуки для нових лідів
Вебхук надсилає кожен новий лід із ваших чат-каналів, наприклад із чату на сайті, Messenger та Instagram, в інший застосунок одразу після того, як лід отримано: у вашу CRM, Zapier, Make, n8n або ваш власний код. KnowStack робить підписаний HTTPS-запит POST з контактами ліда й листуванням на цей момент.
Вебхуки для лідів входять у Business, Enterprise і безкоштовний пробний період. Налаштувати їх можна, якщо ваша роль дозволяє керувати користувачами, наприклад Company Admin.
Як додати вебхук
- Скопіюйте адресу вебхука в застосунку, який має отримувати ліди. Вона має починатися з https://.
- У KnowStack відкрийте «Налаштування», виберіть «Інтеграції» й перейдіть до блоку «Надсилання лідів у CRM».
- У розділі «Додати вебхук» впишіть у поле «Назва» ім'я, яке легко впізнати, вставте адресу в поле «Адреса вебхука» й натисніть «Додати вебхук».
- Скопіюйте ключ підпису, що з'явився. Він починається з whsec_ і показується лише один раз. Потім натисніть «Я зберіг ключ».
- Відкрийте меню вебхука й натисніть «Надіслати тест». Результат з'явиться одразу, а також у розділі «Журнал надсилань».
Надсилаються лише ліди, отримані після додавання вебхука; попередні залишаються в KnowStack. Можна додати кілька вебхуків, і кожен новий лід іде в усі активні.
Адреса має бути публічною: лише https, стандартний порт, без імені користувача й пароля. Адреси в приватній або локальній мережі відхиляються, зокрема якщо публічне ім'я згодом почне вказувати на таку мережу. Переспрямування не виконуються, тому вставте кінцеву адресу.
Коли надсилаються запити
| Подія | Коли | Що містить |
|---|---|---|
| lead.created | Чат отримує новий лід | Лід і листування на цей момент |
| lead.updated | Ім'я, email або телефон з'являються пізніше в тому самому ліді | Поточні дані ліда й список changed з новими полями, без листування |
| test | Ви натискаєте «Надіслати тест» | Приклад ліда з id 0 і короткий приклад листування |
Повідомлення, написані після створення ліда, не надсилаються ніколи. Запит lead.updated іде лише після того, як lead.created було прийнято, і лише якщо поле з порожнього стало заповненим.
Заголовки запиту
| Заголовок | Значення |
|---|---|
| Content-Type | application/json |
| User-Agent | LeadWebhook/1.0 |
| X-Webhook-Event | lead.created, lead.updated або test |
| X-Webhook-Delivery | Ідентифікатор надсилання. Під час повторної спроби того самого надсилання він не змінюється, тож використовуйте його, щоб відсіювати дублікати |
| X-Webhook-Timestamp | Час підпису в секундах Unix |
| X-Webhook-Signature | v1= і 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 |
| transcriptIncomplete | true, якщо старі повідомлення вже видалено за вашими налаштуваннями зберігання. У таких повідомлень text дорівнює null, а purged дорівнює true |
Тіло lead.updated містить ті самі поля version, event, deliveryId, occurredAt і lead з поточними значеннями ліда. Замість листування в ньому є changed — список полів, заповнених після попереднього запиту, наприклад ["phone"].
Перевірка підпису
- Прочитайте вихідне тіло запиту до розбору JSON.
- З'єднайте значення X-Webhook-Timestamp, крапку й вихідне тіло.
- Обчисліть HMAC-SHA256 цього тексту з вашим ключем підпису (повним значенням разом із whsec_) і запишіть його в шістнадцятковому вигляді.
- Порівняйте v1= з цим значенням і заголовок X-Webhook-Signature порівнянням за сталий час.
- Відхиліть запит, якщо мітка часу відрізняється від вашого годинника більш ніж на 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 ще раз». Ліди, що чекають біля призупиненого вебхука або вебхука зі статусом «Потребує уваги», залишаються в черзі й підуть, коли ви підвищите тариф і відновите вебхук. Ваші вебхуки залишаються в списку, і їх і далі можна призупинити або видалити.