All docs Referencia

API + Webhooks

Recibe POST HTTPS en tiempo real a tu CRM, Slack, Zapier, n8n o cualquier otro sistema cuando ocurran eventos en tus chatbots.

Webhooks salientes

Firmado con HMAC SHA-256

Hasta 5 reintentos con retroceso exponencial

Descripción general

DBestChatBot envía webhooks salientes cuando ocurren eventos relevantes en tus chatbots (se captura un lead, comienza o termina una conversación, se envía o recibe un mensaje). Configuras una URL de destino en el panel y enviamos un POST con un sobre JSON en cuestión de segundos tras cada evento.

Los webhooks son una función de Pro / Agency. Free-tier accounts can still view conversations and leads in the dashboard but can't pipe them to external systems.

Eventos

Cada webhook se suscribe a uno o más de estos tipos de eventos:

EventoCuándo se activa
lead.capturedUn visitante envía el formulario previo al chat, O un mensaje entrante de WhatsApp inicia una conversación (siempre tenemos su teléfono). Recomendado para conectar con el CRM.
conversation.startedEmpieza una nueva conversación. Útil para analítica de marketing o para iniciar flujos de seguimiento de inmediato.
conversation.endedVisitor closes the chat, or it goes inactive for 5+ minutes. Good for triggering follow-up emails.
message.receivedEl visitante envió un mensaje. Alto volumen — suscríbete solo si tienes una necesidad concreta.
message.sentLa IA respondió a un visitante. Alto volumen — suscríbete solo si tienes una necesidad concreta.

Formato del payload

Cada webhook envía un sobre JSON con los mismos campos de nivel superior. El data el objeto varía según el tipo de evento. Ejemplo para lead.captured:

{
  "event": "lead.captured",
  "id": "evt_abc123def456",
  "created_at": "2026-05-17T15:30:00+00:00",
  "data": {
    "conversation_id": "conv_xyz789",
    "chatbot": {
      "id": 42,
      "name": "Acme Support"
    },
    "visitor": {
      "name": "Jane Doe",
      "email": "jane@acme.com",
      "phone": "+15551234567"
    },
    "source_url": "https://acme.com/pricing",
    "message_count": 4,
    "transcript_url": "https://dbestchatbot.com/app/conversations/conv_xyz789",
    "capture_method": "prechat_form"
  }
}

Encabezados de la solicitud

Cada solicitud incluye:

  • Content-Type: application/json
  • User-Agent: DBestChatBot-Webhook/1.0
  • X-DBestChatBot-Event: lead.captured — el nombre del evento
  • X-DBestChatBot-Delivery: evt_abc123 — ID de entrega único, úsalo para deduplicar
  • X-DBestChatBot-Signature: t=1747490400,v1=<hex_hmac> — firma de verificación

Verifying signatures (recommended)

Verifica siempre las cargas útiles de los webhooks para asegurarte de que realmente provienen de DBestChatBot. El formato de la firma es compatible con Stripe: una marca de tiempo Unix t y un resumen hexadecimal HMAC-SHA-256 v1, joined with a comma.

Algoritmo:

  1. Extraer t and v1 desde el encabezado
  2. Rechazar si t está a más de 5 minutos de la hora actual (protección contra repetición)
  3. Calcular expected = HMAC_SHA256(signing_secret, "t.raw_request_body")
  4. Comparación en tiempo constante expected with v1
  5. Si coinciden, el payload es auténtico. De lo contrario, recházalo.

Node.js / Express

// Node.js / Express example — verify the signature header
import express from 'express';
import crypto from 'crypto';

const app = express();
const SIGNING_SECRET = process.env.DBESTCHATBOT_SIGNING_SECRET;

// IMPORTANT: use raw body, not parsed JSON, for signature verification
app.post('/webhooks/dbestchatbot',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const header = req.header('X-DBestChatBot-Signature') || '';
    const match = header.match(/t=(\d+),v1=([a-f0-9]+)/);
    if (!match) return res.status(400).send('bad signature header');

    const [, ts, signature] = match;

    // 5-minute replay window
    if (Math.abs(Date.now() / 1000 - parseInt(ts)) > 300) {
      return res.status(400).send('stale timestamp');
    }

    const expected = crypto
      .createHmac('sha256', SIGNING_SECRET)
      .update(`${ts}.${req.body}`)
      .digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
      return res.status(401).send('signature mismatch');
    }

    const event = JSON.parse(req.body.toString());
    console.log('Verified event:', event.event, event.data);

    // Always respond 2xx quickly — we'll retry up to 5x with backoff if you don't
    res.status(200).send('ok');
  },
);

PHP

<?php
// PHP example — verify the signature header
$signingSecret = getenv('DBESTCHATBOT_SIGNING_SECRET');
$rawBody = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_DBESTCHATBOT_SIGNATURE'] ?? '';

if (! preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $m)) {
    http_response_code(400); exit('bad signature header');
}
[, $ts, $signature] = $m;

if (abs(time() - (int) $ts) > 300) {
    http_response_code(400); exit('stale timestamp');
}

$expected = hash_hmac('sha256', "{$ts}.{$rawBody}", $signingSecret);
if (! hash_equals($expected, $signature)) {
    http_response_code(401); exit('signature mismatch');
}

$event = json_decode($rawBody, true);
// process $event['event'], $event['data'] ...

http_response_code(200);
echo 'ok';

Reintentos y garantías de entrega

Reintentamos hasta 5 veces with exponential backoff if your endpoint doesn't return a 2xx response within 30 seconds:

IntentoRetraso desde el anterior
1immediate
2+1 minuto
3+5 minutos
4+30 minutos
5+2 horas

Tras el quinto intento fallido, la entrega se marca como failed y dejamos de reintentar. Puedes ver el registro completo de entregas (incluido el estado HTTP, el mensaje de error y el número de intentos) en la página de detalle del webhook de tu panel.

Devolver siempre un estado 2xx rápidamente. Si necesitas hacer un procesamiento pesado, confirma primero con 200 y procesa de forma asíncrona.

Idempotencia

Cada entrega tiene un único id campo (también enviado como X-DBestChatBot-Delivery). Because we retry on failure, your endpoint may receive the same event more than once. Store the IDs you've already processed and skip duplicates.

Lista de IP permitidas

Los webhooks salientes se originan en nuestros servidores de producción en 15.204.199.41. Si usas una lista de IPs permitidas, permite esta dirección. No obstante, las firmas son el método de verificación más fiable — la IP se puede falsificar, HMAC no (sin el secreto).

Primeros pasos

  1. Ir a Webhooks en tu panel
  2. Haz clic Añadir endpoint — pega tu URL, elige eventos
  3. Copiar el secreto de firma se muestra después de la creación
  4. Envía un evento de prueba para verificar que tu endpoint lo recibe y lo valida
  5. Observa cómo fluyen los eventos reales mientras los visitantes usan tus chatbots

Conectando con Zapier / Make / n8n

All three tools have a generic "Catch Hook" or "Webhook Trigger" action — paste the URL they generate into a new endpoint here, subscribe to the events you want, done. Map fields from data.visitor a tu CRM, Sheets o donde sea desde ahí.

HubSpot — recorrido completo

Esta es la configuración más común. Registra cada lead del chatbot como un Contacto de HubSpot:

  1. En Zapier, haz clic en Crear Zap → Activador: Webhooks by Zapier → evento Catch Hook → para continuar. Zapier te muestra una URL personalizada como https://hooks.zapier.com/hooks/catch/12345/abc/
  2. En DBestChatBot, ve a Webhooks → Añadir endpoint. Paste the Zapier URL, name it "HubSpot via Zapier," subscribe to lead.captured, guardar.
  3. De vuelta en Zapier: haz clic Test trigger. Luego, en tu página de webhook de DBestChatBot, haz clic en Enviar evento de prueba. Zapier debería recibir una carga útil de ejemplo: el ejemplo incluye data.visitor.name, data.visitor.email, data.visitor.phone, y cualquier campo personalizado previo al chat que hayas definido.
  4. En Zapier, añade una Acción → HubSpot → evento Crear o actualizar contacto. Autoriza tu cuenta de HubSpot.
  5. Asigna los campos:
    • HubSpot email ← Zapier data.visitor.email
    • HubSpot firstname ← Zapier data.visitor.name (separa nombre/apellido si lo necesitas)
    • HubSpot phone ← Zapier data.visitor.phone
    • HubSpot company ← Zapier data.visitor.company (if you added a custom "Company" field in your chatbot's pre-chat form)
    • HubSpot lifecycle_stage → codifica directamente en Lead or Suscriptor
    • HubSpot website ← Zapier data.source_url
  6. Opcional pero recomendado: añade una segunda acción → HubSpot → Crear nota en ese contacto con la URL del historial del chat data.transcript_url como cuerpo de la nota. Tu equipo de ventas hace clic en el enlace y ve la conversación completa que llevó a la captura.
  7. Activa el Zap. Cada futuro lead.captured el evento crea / actualiza un Contacto de HubSpot en segundos.

Consejo Pro: if you want to route HIGH-VALUE leads differently (e.g. enterprise pricing inquiries) from FAQ-style chats, add a custom field to your pre-chat form like "What are you looking to do?" with options "Just browsing / Buying / Sales question." Then in Zapier add a Filter step that only continues to HubSpot if the answer is "Sales question" — your CRM stays clean.

Otros CRM: el mismo patrón funciona para Pipedrive (acción: Create Deal), Salesforce (acción: Create/Update Lead), Close (acción: Create Lead), monday.com (acción: Create Item) y Airtable (acción: Create Record). El lado de DBestChatBot es idéntico: solo apunta un Zap diferente a la misma URL de webhook.

FAQ

Why isn't my endpoint receiving events?

  • Verifica que el webhook esté active en el panel
  • Check you're subscribed to the right event type
  • Revisa el registro de entregas en la página de detalles del webhook para ver errores HTTP
  • Use the Enviar evento de prueba button to bypass real-world triggers

¿Cómo dejo de recibir eventos temporalmente?

Toggle the webhook off — no events are queued or buffered, they're simply dropped.

¿Puedo obtener eventos anteriores que ya ocurrieron?

No, los webhooks son de envío único. Para datos históricos, usa el panel Conversaciones exporta (CSV) o contáctanos para una carga inicial puntual.

¿Listo para conectarlo?

Abrir panel de Webhooks