Обзор вебхуков
Вебхуки позволяют ChatLab уведомлять ваши системы в тот самый момент, когда в ваших чатботах что-то происходит. Вместо постоянного опроса Management API или экспорта данных вручную вы регистрируете HTTPS-эндпоинт, и ChatLab отправляет на него подписанный HTTP POST в реальном времени - когда посетитель оставляет лид, отправляет контактную форму, оценивает диалог, запрашивает оператора или когда выполняется действие ИИ.
Типичные сценарии использования:
- передача новых лидов прямо в вашу CRM в секунду их получения
- уведомление команды в Slack, когда посетитель запрашивает live chat (чат с оператором)
- передача оценок и сводок диалогов в вашу собственную систему аналитики
- мониторинг выполнения AI action (действий ИИ) и оповещения об ошибках
Доступность: ваш аккаунт должен включать функцию Webhooks.
Где настроить: в приложении администратора перейдите в Account settings -> Webhooks (Настройки аккаунта -> Вебхуки) рядом с разделом Management API. Вебхуки действуют на уровне аккаунта - один эндпоинт может получать события от всех ваших ботов или от одного выбранного бота.
Настройка эндпоинта
- Перейдите в Account settings -> Webhooks и нажмите Add endpoint (Добавить эндпоинт).
- Заполните форму эндпоинта:
- Name (Название) - метка для вашего удобства, например, "CRM sync" или "Slack alerts".
- URL - адрес HTTPS, на который ChatLab будет отправлять события через POST.
- Events (События) - выберите типы событий, которые должен получать этот эндпоинт (см. каталог ниже). Выбирайте только то, что вам нужно: события с высоким объемом трафика, такие как
ai_action.executed, могут создавать большую нагрузку. - Bot filter (Фильтр ботов) (необязательно) - выберите одного бота или All bots (Все боты) для всех ботов вашего аккаунта.
- Custom form filter (Фильтр пользовательских форм) (необязательно) - перенаправляет отправки одной конкретной формы на этот эндпоинт. Это фильтрует только событие
custom_form.submitted; все остальные события, на которые вы подписались (лиды, запросы на контакт, диалоги, live chat, действия ИИ), доставляются независимо от этой настройки.
- Отправьте форму. Secret (секрет) эндпоинта отображается ровно один раз в окне успешного создания - скопируйте его прямо сейчас и сохраните в надежном месте. Он понадобится вам для проверки подписей (см. раздел "Безопасность" ниже). Получить его в виде открытого текста позже невозможно.
У каждого эндпоинта также есть:
- Переключатель включения/отключения - приостановка доставки без удаления эндпоинта. Отключенные эндпоинты просто отбрасывают события (они не ставятся в очередь для отправки позже).
- Send sample event (Отправить тестовое событие) - отправляет подписанный тестовый запрос на ваш URL, чтобы вы могли проверить приемник сквозным образом. Вы можете выбрать тип события и отредактировать примеры значений перед отправкой, чтобы ваш обработчик получил реалистичные данные. Тест приходит как обычная доставка с
eventType, соответствующим вашему выбору (или какwebhook.testдля простой проверки соединения). - Roll secret (Сменить секрет) - генерирует новый секрет и аннулирует старый. Используйте это, если секрет мог быть скомпрометирован. Новый секрет также показывается только один раз. Для контролируемой смены приостановите эндпоинт, обновите и скопируйте новый секрет, внесите изменения на стороне приемника, затем снова включите эндпоинт и отправьте тестовое событие. События, произошедшие во время паузы, не ставятся в очередь. Запланируйте этот перерыв перед сменой ключа.
- Delivery log (Журнал доставок) - список последних доставок для конкретного эндпоинта с указанием времени, типа события, возвращенного вашим сервером HTTP-статуса и времени ответа. Здесь отображаются неудачные доставки и паузы механизма circuit breaker. Журнал хранится в течение 14 дней.
Структура события
Каждая доставка представляет собой HTTP POST с заголовком Content-Type: application/json. Тело всегда имеет одну и ту же базовую структуру (envelope); объект data зависит от типа события:
{
"eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
"eventType": "lead.created",
"timestamp": "2026-08-13T14:22:31Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": { }
}
eventId- уникальный идентификатор события. Используйте его для дедупликации, если обработка на вашей стороне должна быть идемпотентной.eventType- один из типов, описанных ниже; также передается в заголовкеX-ChatLab-Event.timestamp- время формирования структуры доставки по стандарту ISO 8601 в формате UTC.botId/botName- бот, к которому относится событие.conversationId/sessionId- контекст диалога, если применимо.
Каталог событий
lead.created
Срабатывает, когда посетитель отправляет свои контактные данные - через форму сбора лидов, предварительную форму Live Chat или пользовательскую форму, настроенную для сбора лидов.
{
"eventId": "9f1c1c8e-6a2b-4b9e-9d2f-3f8a1e2b4c5d",
"eventType": "lead.created",
"timestamp": "2026-08-13T14:22:31Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"email": "jane.doe@example.com",
"name": "Jane Doe",
"phone": "+1 555 0123",
"source": "LEAD_COLLECTION_FORM",
"formCodeName": "lead_form",
"formName": "Lead form",
"fields": [
{"name": "email", "value": "jane.doe@example.com", "type": "email"},
{"name": "company", "value": "Acme Inc.", "type": "text"},
{"name": "topics", "value": ["Billing", "Delivery"], "type": "multichoice"},
{"name": "attachment", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
],
"pageUrl": "https://acme.com/pricing"
}
}
source- способ получения контактных данных:LEAD_COLLECTION_FORM(форма сбора лидов),LIVE_CHAT_FORM(предварительная форма Live Chat),CONVERSATION(ИИ получил данные в ходе диалога),ADMIN_DATA_UPDATEилиUPDATE_CLIENT_CONTEXT(данные изменены на стороне ChatLab). Отправка формы связи с оператором никогда не вызывает это событие - вместо него срабатываетcontact_form.submitted.email,name,phone- контактные данные, сопоставленные с записью лида.- Когда для сбора лидов используется пользовательская форма, каждое настроенное в ней поле включается в
fieldsв исходном порядке, аformCodeName/formNameидентифицируют эту форму. В классической форме сбора лидов оба этих параметра равныnull, аfieldsпредставляет собой пустой массив. - Каждый элемент в
fieldsимеет структуру{name, value, type}.name- техническое имя поля, которое остается неизменным при редактировании подписи; используйте его для сопоставления полей в вашей CRM. - Для полей типа
multichoiceзначениеvalueпредставляет собой массив выбранных вариантов. Поля-чекбоксы передаются отдельными записями со значениями"true"/"false". - Для полей типа
fileзначениеvalueявляется ссылкой на скачивание загруженного файла; вебхук никогда не содержит тело самого файла. pageUrl- страница, на которой находился посетитель в момент отправки формы.
contact_form.submitted
Срабатывает, когда посетитель отправляет форму связи с оператором или пользовательскую форму, предназначенную для связи с человеком.
{
"eventId": "3a7b9c2d-1e4f-4a6b-8c0d-5e2f7a9b1c3d",
"eventType": "contact_form.submitted",
"timestamp": "2026-08-13T14:25:02Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"email": "jane.doe@example.com",
"message": "I need help with my last invoice.",
"source": "CUSTOM_FORM",
"formCodeName": "contact_form",
"formName": "Contact form",
"fields": [
{"name": "email", "value": "jane.doe@example.com", "type": "email"},
{"name": "order_number", "value": "A-10293", "type": "text"},
{"name": "message", "value": "I need help with my last invoice.", "type": "textarea"}
]
}
}
email- адрес, оставленный посетителем, на который ваша служба поддержки должна отправить ответ.source- значениеCUSTOM_FORM, если в основе лежит пользовательская форма, илиCONTACT_FORMдля стандартной встроенной формы.formCodeName/formName- идентификаторы пользовательской формы, на основе которой создан запрос; оба параметра равныnullдля встроенной формы.- При использовании пользовательской формы каждое настроенное в ней поле включается в массив
fields(в том же формате{name, value, type}, что и вlead.created). Для встроенной формы заполняются толькоemailиmessage,fieldsостается пустым массивом, а идентификаторы формы равныnull. message- сопоставленное поле сообщения или все заполненные значения, объединенные вместе, если в форме нет отдельного поля для сообщения.
custom_form.submitted
Срабатывает при каждой отправке пользовательской формы, независимо от ее назначения. Обратите внимание: формы, настроенные для сбора лидов или связи с оператором, также инициируют соответствующие события lead.created / contact_form.submitted. Подписывайтесь на один из типов событий в зависимости от того, нужен ли вам универсальный или специализированный формат данных, чтобы избежать дублирования бизнес-логики. У этих семейств событий разные ID; связка conversationId и timestamp не является надежным идентификатором конкретной отправки.
{
"eventId": "6c1d8e3f-2a5b-4c7d-9e0f-1a4b6c8d0e2f",
"eventType": "custom_form.submitted",
"timestamp": "2026-08-13T14:27:45Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"formCodeName": "warranty_claim",
"formName": "Warranty claim",
"fields": [
{"name": "order_number", "value": "A-10293", "type": "text"},
{"name": "issue", "value": "Damaged on arrival", "type": "textarea"},
{"name": "photo", "value": "https://api.chatlab.com/aichat/customform/download?key=...&token=...", "type": "file"}
],
"purpose": "STANDALONE"
}
}
formCodeName- постоянное системное имя формы, которое не меняется при ее переименовании; используйте его для маршрутизации отправленных данных в вашей системе.formName- отображаемое название формы, которое видят посетители.fieldsсодержит элементы того же формата{name, value, type}, что иlead.created: варианты из полей множественного выбора передаются в виде массивов, а файлы - в виде ссылок на скачивание.purpose-STANDALONE,LEAD_COLLECTIONилиHUMAN_CONTACT, в зависимости от роли формы в настройках чат-бота.
conversation.started
Срабатывает, когда посетитель отправляет первое сообщение в новом диалоге.
{
"eventId": "8e2f0a4b-3c6d-4e8f-a1b2-2c5d7e9f1a3b",
"eventType": "conversation.started",
"timestamp": "2026-08-13T14:20:11Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"firstMessage": "Do you ship to Canada?",
"chatSource": "WIDGET",
"byAdmin": false,
"countryCode": "PL",
"ipAddress": "83.12.44.7"
}
}
firstMessage- точный текст первого сообщения посетителя. Значение равноnull, если диалог был начат без текста сообщения.chatSource- канал поступления диалога:WIDGET,WHATSAPP,MESSENGER,VOICE,VOICE_PHONE,API,BOOKING,AIRBNBилиIDOBOOKING.byAdmin- значениеtrue, если диалог открыт в окне предпросмотра чат-бота внутри панели управления ChatLab, а не реальным посетителем. Используйте этот флаг, чтобы отфильтровать собственные тестовые чаты от передачи в CRM.countryCode- код страны ISO, определенный по IP-адресу посетителя;null, если страну определить не удалось.ipAddress- IP-адрес посетителя, зафиксированный сервером ChatLab;null, если адрес недоступен. Эти данные подпадают под действие GDPR как персональные данные - сохраняйте их только при наличии законных оснований.
conversation.rated
Срабатывает, когда посетитель ставит положительную или отрицательную оценку диалогу (см. Оценка диалога).
{
"eventId": "1b4c6d8e-5f0a-4b2c-8d3e-4f7a9b1c3d5e",
"eventType": "conversation.rated",
"timestamp": "2026-08-13T14:31:09Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"rating": "POSITIVE"
}
}
rating- значениеPOSITIVEилиNEGATIVE. Сброс оценки не генерирует событие, поэтому нейтральные значения не передаются.
conversation.summarized
Срабатывает, когда ChatLab формирует саммари завершенного диалога.
{
"eventId": "4d7e9f1a-6b2c-4d4e-9f0a-5b8c0d2e4f6a",
"eventType": "conversation.summarized",
"timestamp": "2026-08-13T14:45:00Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"summary": "Visitor asked about shipping to Canada and delivery times. The bot confirmed availability and quoted 5-7 business days. Visitor left satisfied.",
"language": "en_US"
}
}
summary- сгенерированный текст саммари. Генерация выполняется асинхронно и зависит от настроек саммари у бота и очереди обработки; не рассчитывайте на фиксированное время доставки.language- внутренняя локаль бота, переданная для формирования саммари (например,en_US); этот параметр может отличаться от языка, на котором общался посетитель.
client.summarized
Срабатывает, когда ChatLab обновляет ИИ-профиль клиента. Профиль формируется заново на базе предыдущего профиля и саммари только что завершенного диалога, поэтому событие может приходить позже conversation.summarized. Порядок доставки не гарантируется. Пейлоад содержит email, если он известен, однако в базе ChatLab могут быть клиенты и без email-адреса.
{
"eventId": "b5d8f1a3-7c2e-4d9b-a6f0-1e3c5a7b9d2f",
"eventType": "client.summarized",
"timestamp": "2026-08-18T09:12:04Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"clientEmail": "jane.doe@example.com",
"client": {
"email": "jane.doe@example.com",
"name": "Jane Doe",
"phone": "+1 555 0123",
"countryCode": "PL",
"ipAddress": "83.12.44.7"
},
"clientSummary": "Returning customer interested in international shipping. Asked about delivery times to Canada twice and about return costs once."
}
}
clientEmail- идентификатор для сопоставления клиента с вашей CRM. Он равенnullдля анонимных посетителей, не оставивших адрес (для них событие тоже срабатывает) - пропускайте такие вебхуки, если в вашей интеграции ключом является e-mail.client- контактные данные, зафиксированные для данного пользователя в ChatLab:email,name,phone,countryCodeиipAddress. Все ключи присутствуют всегда; неизвестные значения равныnull.clientSummary- полный текст профиля в виде обычного текста (не diff). Он полностью заменяет предыдущее саммари, поэтому сохраняйте его с перезаписью, а не добавляйте в конец.- Профиль пересчитывается только для ботов со включенной функцией памяти чата и только для тех диалогов, пауза в которых была достаточной для создания саммари. Это событие приходит не моментально, а через несколько минут после завершения диалога.
live_chat.requested
Срабатывает, когда ИИ передает диалог в Live Chat - либо по запросу посетителя, либо по решению бота о необходимости привлечь человека.
{
"eventId": "7a0b2c4d-8e3f-4a5b-b0c1-6d9e1f3a5b7c",
"eventType": "live_chat.requested",
"timestamp": "2026-08-13T14:33:20Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"requestedBy": "AI"
}
}
requestedBy- в настоящее время всегдаAI, поскольку передача диалога всегда инициируется действием бота, даже если посетитель запросил оператора текстом. Рекомендуется обрабатывать это поле как открытый enum: предусмотрите поведение для неизвестных значений, не ограничиваясь проверкой на равенствоAI.- Это событие фиксирует сам факт запуска действия по передаче диалога со стороны ИИ, а не любой возможный вход в live chat. Оно не гарантирует, что оператор уже подключился.
live_chat.started
Срабатывает, когда сессия live chat создана после отправки посетителем формы перевода на оператора. Это происходит еще до того, как оператор обязательно подключится или ответит; не считайте это подтверждением реального участия человека.
{
"eventId": "0c3d5e7f-9a4b-4c6d-a1b2-7e0f2a4b6c8d",
"eventType": "live_chat.started",
"timestamp": "2026-08-13T14:33:55Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {}
}
- Объект
dataнамеренно оставлен пустым. Все необходимые сведения находятся в заголовке события:botIdидентифицирует чат-бота, аconversationId/sessionIdсвязывают событие с конкретным диалогом. Вы можете получить это событие без предварительногоlive_chat.requested- например, если посетитель воспользовался кнопкой вызова live chat в самом виджете.
live_chat.ended
Срабатывает при завершении сессии live chat.
{
"eventId": "2e5f7a9b-0c5d-4e7f-b2c3-8f1a3b5c7d9e",
"eventType": "live_chat.ended",
"timestamp": "2026-08-13T14:52:41Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"durationSeconds": 1126
}
}
durationSeconds- длительность сессии live chat в секундах, отсчитываемая от момента создания сессии, включая время ожидания оператора. В редких ситуациях, когда сессия закрылась, так и не начавшись, это поле опускается.
ai_action.executed
Срабатывает каждый раз, когда бот выполняет действие ИИ - вызов встроенной интеграции или пользовательскую функцию API. Это высоконагруженное событие: активный e-commerce бот может совершать сотни действий в день, а одна реплика посетителя может вызвать сразу несколько действий подряд. Настройте для него отдельный эндпоинт или убедитесь, что ваш сервер справится с таким объемом запросов.
{
"eventId": "5f8a0b2c-1d6e-4f8a-c3d4-9a2b4c6d8e0f",
"eventType": "ai_action.executed",
"timestamp": "2026-08-13T14:21:03Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"actionName": "search_products",
"status": "SUCCESS",
"durationMs": 842,
"errorMessage": null
}
}
actionName- имя выполненного действия так, как его видит ИИ: например,search_productsдля готовой интеграции или заданное вами имя для пользовательского действия API.status- значениеSUCCESSилиERROR.durationMs- время выполнения действия в миллисекундах. Удобно для выявления медленных интеграций до того, как на них начнут жаловаться посетители.errorMessage- причина ошибки; заполняется только при статусеERROR, во всех остальных случаях имеет значениеnull.
webhook.test
Отправляется по нажатию кнопки Send sample event (Отправить тестовое событие) при базовой проверке связи. Подписывается точно так же, как и реальные события.
{
"eventId": "9b2c4d6e-3f8a-4b0c-d5e6-0b3c5d7e9f1a",
"eventType": "webhook.test",
"timestamp": "2026-08-13T14:10:00Z",
"botId": 1234,
"botName": "Support Bot",
"conversationId": "conv_a1b2c3",
"sessionId": "sess_x9y8z7",
"data": {
"message": "Test delivery from ChatLab"
}
}
message- постоянный текст сообщения, неизменный во всех тестовых доставках. Поля заголовка содержат демонстрационные значения, поэтому никогда не обрабатывайте вебхукwebhook.testкак реальные боевые данные.- Это единственный тип события, на который нельзя подписаться вручную в настройках эндпоинта: он отправляется по запросу из панели управления и доставляется строго на тот адрес, для которого была нажата кнопка, независимо от списка выбранных событий.
Безопасность: проверка подлинности доставки
Каждый входящий запрос содержит четыре HTTP-заголовка:
| Заголовок | Значение |
|---|---|
X-ChatLab-Signature |
sha256=<hex hmac> - подпись HMAC-SHA256 для тела запроса |
X-ChatLab-Timestamp |
Время формирования подписи в формате Unix time (в секундах) |
X-ChatLab-Event |
Тип события, например lead.created |
X-ChatLab-Delivery |
Уникальный ID доставки, совпадающий со значением eventId в теле запроса |
Подпись рассчитывается как HMAC-SHA256 от строки {timestamp}.{rawBody} с использованием секретного ключа вашего эндпоинта, где {timestamp} - значение заголовка X-ChatLab-Timestamp, а {rawBody} - исходное, нераспарсенное тело запроса. Всегда проверяйте подпись по исходным байтам - повторная сериализация распарсенного JSON изменит последовательность байтов и сделает подпись недействительной.
Для защиты от атак повторного воспроизведения (replay attacks) отклоняйте запросы, значение X-ChatLab-Timestamp в которых отличается от текущего времени более чем на 5 минут.
Node.js
const crypto = require('crypto');
function verifyChatLabSignature(req, secret) {
const signature = req.headers['x-chatlab-signature'];
const timestamp = req.headers['x-chatlab-timestamp'];
if (typeof signature !== 'string' || typeof timestamp !== 'string') return false;
if (!/^\d+$/.test(timestamp) || !Number.isSafeInteger(Number(timestamp))) return false;
if (!Buffer.isBuffer(req.rawBody)) return false;
// Reject stale deliveries (older than 5 minutes)
const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
if (ageSeconds > 300) return false;
// rawBody must be the raw request body bytes, not re-serialized JSON.
// With Express: app.use(express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }))
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(timestamp + '.')
.update(req.rawBody)
.digest('hex');
const a = Buffer.from(signature);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
PHP
<?php
function verifyChatLabSignature(string $secret): bool
{
$signature = $_SERVER['HTTP_X_CHATLAB_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_CHATLAB_TIMESTAMP'] ?? '';
if ($signature === '' || $timestamp === '' || !ctype_digit($timestamp)) {
return false;
}
// Reject stale deliveries (older than 5 minutes)
if (abs(time() - (int) $timestamp) > 300) {
return false;
}
$rawBody = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
return hash_equals($expected, $signature);
}
Если проверка не пройдена, верните ответ со статусом 401 и отклоните полученные данные. Никогда не обрабатывайте неподтвержденные запросы: любой, кто узнает адрес вашего эндпоинта, сможет отправлять на него произвольные данные JSON.
Поведение доставки
Ознакомьтесь с этими правилами доставки, прежде чем приступать к разработке на базе webhook:
- Отвечайте быстро. Ваш эндпоинт должен ответить в течение 3 секунд, иначе попытка доставки будет считаться неудачной. Проверьте подпись, надежно поставьте событие в очередь и верните статус
2xxв пределах этого интервала. Более медленные вызовы CRM и бизнес-логику выполняйте асинхронно. - Fire-and-forget, не более одного раза. Подходящие включенные эндпоинты получают не более одной попытки доставки - повторных попыток нет. Приостановленные эндпоинты и разомкнутые цепи могут отменить даже эту попытку. Если ваш эндпоинт недоступен, превышает таймаут или возвращает статус, отличный от 2xx, событие теряется и не будет отправлено повторно. Webhook - это уведомления, а не реплицированное хранилище данных: используйте эндпоинты диалогов Bot Talk API или экспорт лидов для синхронизации сохраненных данных там, где это поддерживается. Management API охватывает настройки ботов и данные об использовании, но не полный архив событий. Некоторые события невозможно восстановить через эти интерфейсы.
- Автоматический выключатель (circuit breaker). После 5 неудачных доставок подряд для пары эндпоинт/бот доставки для этой пары приостанавливаются на 5 минут. События, происходящие во время паузы, отбрасываются, а в журнале доставок появляются записи
CIRCUIT_OPENдля обозначения отмененных попыток. Доставки, пропущенные из-за разомкнутой цепи, не учитываются при автоматическом отключении. - Автоматическое отключение. Проверка выполняется в момент неудачной доставки, а не по расписанию. Если доставка не удалась и в течение 7 дней не было ни одной успешной доставки - отсчет ведется от последнего успеха или от даты создания эндпоинта, если успешных доставок не было вовсе - эндпоинт отключается, а вы получаете уведомление по электронной почте. Любой статус
2xxв любой момент сбрасывает этот таймер. Эндпоинт, который не получает трафик, никогда не отключается, поскольку в нем нет сбоев. Включите его снова в Account settings (настройки аккаунта), когда исправите свой приемник; счетчик сбоев и отметка автоотключения сбрасываются при повторном включении, а события, пропущенные во время отключения, задним числом не отправляются. - 410 Gone. Если ваш эндпоинт отвечает с HTTP-статусом
410 Gone, ChatLab немедленно отключает его. Используйте это для программного вывода эндпоинта из эксплуатации на стороне приемника. - Идемпотентность. В штатном режиме дублирование доставок не ожидается, но если ваша обработка требует строгой идемпотентности, выполняйте дедупликацию по
eventId(также доступен в заголовкеX-ChatLab-Delivery).
Порядок доставки не гарантируется. Сохраняйте идентификатор события и делайте бизнес-обработку идемпотентной. Самостоятельно настраивайте сроки хранения и права доступа для полезных нагрузок webhook, так как они могут содержать персональные данные и ссылки на скачивание файлов.
В примерах подписи используются Node.js crypto и функция hash_equals в PHP. Получайте необработанное тело запроса (raw body) до его парсинга.
Лимиты
- До 10 webhook-эндпоинтов на аккаунт.
- Срок хранения журнала доставок: 14 дней. Более старые записи удаляются автоматически.
Связанные статьи
- Сбор лидов - форма, инициирующая
lead.created - Контактная форма связи со специалистом - форма, инициирующая
contact_form.submitted - Live Chat - сценарий работы событий
live_chat.* - Оценка диалога - пальцы вверх/вниз, инициирующие
conversation.rated - AI Actions - интеграции, инициирующие
ai_action.executed - Chat API - колбэки виджета в браузере (клиентский аналог webhook)
- Management API - REST API для управления ботами и данными об использовании