Вебхук — самый гибкий способ забирать заявки из ДелоВход в реальном времени. Как только посетитель оставляет лид в любом виджете (Ловец лидов, квиз, видео-виджет, онлайн-чат), ДелоВход отправляет на ваш адрес HTTP-запрос с данными заявки. Дальше вы делаете с ними что угодно: кладёте в свою CRM, базу, таблицу, шлёте в мессенджер или запускаете автоматизацию. Эта инструкция разбирает настройку по шагам и описывает формат данных, проверку подписи и поведение при ошибках.

Что такое вебхук и кому он нужен

Вебхук (webhook) — это обратный вызов по HTTP: вместо того чтобы вы опрашивали ДелоВход «нет ли новых лидов», система сама шлёт POST-запрос на указанный вами URL в момент появления заявки. Тело запроса — JSON с данными лида.

Вебхук стоит выбрать, если:

  • у вас своя CRM или самописный бэкенд, и нужна доставка лидов туда напрямую;
  • хочется запустить собственную автоматизацию (Make, n8n, свой скрипт);
  • нужен полный контроль над данными заявки, включая UTM-метки, ответы квиза и загруженные файлы.

Если у вас amoCRM или Битрикс24 — проще подключить готовую интеграцию из каталога. Вебхук нужен именно для нестандартных приёмников.

Как включить вебхук в кабинете

  1. Откройте раздел «Интеграции» в личном кабинете и выберите карточку «Вебхук».
  2. Укажите URL приёмника. Это адрес на вашем сервере, который принимает POST с JSON. Допускается только публичный HTTPS-адрес: локальные (localhost, 127.0.0.1) и адреса внутренних сетей отклоняются ради безопасности.
  3. Задайте секрет для подписи. Любая случайная строка. Ею ДелоВход подпишет тело каждого запроса, а вы проверите подпись на своей стороне и убедитесь, что запрос пришёл действительно от ДелоВход, а не от постороннего.
  4. Сохраните и проверьте доставку. Первые заявки появятся во вкладке «Журнал доставки» с кодом ответа вашего сервера.

Дополнительные настройки — фильтр источников, число повторов, таймаут и свои заголовки — находятся на вкладке «Настройки» карточки интеграции.

Что приходит в запросе

Запрос всегда отправляется методом POST с заголовком Content-Type: application/json, тело — в кодировке UTF-8. Вместе с телом приходят служебные заголовки:

  • X-Lead-Source — тип источника лида (например, lead_widget);
  • X-Lead-Id — числовой ID лида;
  • X-Lead-Signature — подпись тела вида sha256=<hex> (если задан секрет);
  • User-Agent: Delovhod-Webhook/1.0.

Пример тела запроса:

{
  "lead_id": 4821,
  "source_type": "lead_widget",
  "source_id": "w-12ab",
  "source_name": "Ловец лидов",
  "user_id": 1,
  "project_id": 7,
  "name": "Алина Соколова",
  "phone": "+7 916 442-08-12",
  "email": "alina.s@gmail.com",
  "message": "Хочу рассчитать кухню",
  "utm": { "utm_source": "yandex", "utm_medium": "cpc", "utm_campaign": "kitchen_msk" },
  "extra": {
    "answers": { "Тип кухни": "Угловая", "Бюджет": "до 300 000 ₽" },
    "socials": { "telegram": "@alina_s" },
    "files": ["https://cdn.delovhod.ru/uploads/plan.pdf"]
  },
  "crm_pipeline_id": null,
  "crm_stage_id": null,
  "positions": [],
  "amount_from_products": null,
  "yandex_client_id": "1718000000000000000",
  "yclid": null,
  "created_at": "2026-06-02T14:48:12+03:00"
}

Назначение полей:

ПолеТипОписание
lead_idnumberID лида в ДелоВход — уникальный, используйте для защиты от дублей.
source_typestringИсточник: lead_widget, video_widget, quiz_widget, online_chat, inbound_api.
source_idstringUUID виджета или квиза, с которого пришёл лид.
source_namestringЧеловекочитаемое название источника.
user_idnumberID владельца аккаунта.
project_idnumberID проекта, к которому привязан лид.
namestring | nullИмя, если посетитель его указал.
phonestring | nullТелефон в том виде, как ввёл посетитель.
emailstring | nullEmail, если был в форме.
messagestring | nullТекст сообщения или комментарий.
utmobjectUTM-метки визита. Может быть пустым объектом.
extraobjectДоп. данные: answers (ответы квиза), socials (мессенджеры), files (ссылки на загрузки).
crm_pipeline_idstring | nullЦелевая воронка CRM. Только для inbound-API, иначе null.
crm_stage_idstring | nullЦелевой этап воронки. Только для inbound-API, иначе null.
positionsarrayСостав заказа [{ name, qty, price }]. Только для inbound-API, иначе пустой массив.
amount_from_productsbool | nullСчитать сумму сделки из позиций. Только для inbound-API.
yandex_client_idstring | nullЯндекс Метрика ClientID посетителя для сквозной аналитики.
yclidstring | nullЯндекс Директ yclid из рекламного клика.
created_atstringВремя создания лида в формате ISO 8601 (UTC).

Поля раздела «только inbound-API» для лидов из виджетов приходят пустыми (null или []), но всегда присутствуют — формат стабилен, новые поля добавляются обратносовместимо.

Как проверить подпись

Если вы задали секрет, ДелоВход подписывает тело запроса алгоритмом HMAC-SHA256 и кладёт результат в заголовок X-Lead-Signature в формате sha256=<hex>. Чтобы убедиться, что запрос подлинный, пересоберите HMAC от сырых байт тела своим секретом и сравните с заголовком. Важно брать именно исходные байты запроса, а не повторно сериализованный JSON — иначе подпись не сойдётся. Сравнивайте в постоянном времени (constant-time), чтобы не давать подсказок атакующему.

Node.js:

import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(req, secret) {
  const header   = req.headers['x-lead-signature'] || '';
  const received = header.replace(/^sha256=/, '');
  const expected = createHmac('sha256', secret)
    .update(req.rawBody)            // сырые байты тела, не re-stringify
    .digest('hex');
  return timingSafeEqual(
    Buffer.from(received, 'hex'),
    Buffer.from(expected, 'hex'),
  );
}

PHP:

function verify(string $rawBody, string $header, string $secret): bool {
    $received = preg_replace('/^sha256=/', '', $header);
    $expected = hash_hmac('sha256', $rawBody, $secret);
    return hash_equals($expected, $received);
}

Python:

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    received = header.removeprefix("sha256=")
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received)

Коды ответа, повторы и таймаут

ДелоВход смотрит на HTTP-код, которым ответил ваш сервер, и решает, что делать дальше:

  • 2xx — лид принят, доставка закрыта успешно. Отвечайте 2xx только после того, как реально сохранили заявку.
  • 5xx, 429 или сетевая ошибка/таймаут — временная проблема. ДелоВход повторит доставку по нарастающему графику: 30 секунд → 2 минуты → 10 минут → 1 час → 6 часов → 24 часа (до 6 попыток).
  • 4xx (кроме 429) — терминальная ошибка. Повторов не будет, лид помечается как недоставленный. Это сигнал, что не так с настройкой: неверный URL, авторизация или формат.

На вкладке «Настройки» можно задать таймаут запроса (1–60 секунд, по умолчанию 10), число повторов и собственные заголовки (например, для авторизации на вашем приёмнике), а также фильтр источников — слать на вебхук только лидов из выбранных виджетов.

Частые проблемы

  • Подпись не сходится. Чаще всего причина — повторная сериализация тела. Считайте HMAC от исходных байт запроса (rawBody), а не от объекта, который вы заново превратили в JSON.
  • Лиды не доходят, в журнале 4xx. Это терминальная ошибка без повторов. Проверьте, что URL правильный, приёмник отвечает 2xx и не требует заголовков, которых вы не настроили.
  • Сохранили localhost или внутренний адрес. Такие адреса отклоняются защитой от SSRF. Приёмник должен быть доступен из интернета по публичному HTTPS.
  • Сервер отвечает медленно. Если приёмник не уложился в таймаут, попытка считается временной ошибкой и уходит в повтор. Принимайте лид быстро, тяжёлую обработку выносите в фон.

Коротко

Укажите публичный HTTPS-URL и секрет, проверяйте подпись X-Lead-Signature по сырому телу, отвечайте 2xx после приёма лида — и заявки из всех виджетов ДелоВход будут падать к вам в реальном времени. Временные сбои система переживёт сама за счёт повторов, а вкладка «Журнал доставки» всегда покажет, что и когда было отправлено.