All docs Riferimento

API + Webhooks

Ricevi POST HTTPS in tempo reale verso il tuo CRM, Slack, Zapier, n8n o qualsiasi altro sistema quando accadono eventi nei tuoi chatbot.

Webhook in uscita

Firmato con HMAC SHA-256

Fino a 5 tentativi con backoff

Panoramica

DBestChatBot invia webhook in uscita quando accadono eventi significativi sui tuoi chatbot (viene acquisito un lead, inizia o termina una conversazione, viene inviato o ricevuto un messaggio). Configuri un URL di destinazione nella dashboard e noi inviamo via POST un envelope JSON entro pochi secondi da ogni evento.

Webhooks are a Pro / Agency feature. Free-tier accounts can still view conversations and leads in the dashboard but can't pipe them to external systems.

Eventi

Ogni webhook si iscrive a uno o più di questi tipi di evento:

EventoQuando si attiva
lead.capturedUn visitatore invia il modulo pre-chat, OPPURE un messaggio WhatsApp in entrata avvia una conversazione (abbiamo sempre il suo numero). Consigliato per il collegamento al CRM.
conversation.startedInizia una nuova conversazione. Utile per le analisi di marketing o per avviare subito flussi di follow-up.
conversation.endedIl visitatore chiude la chat o resta inattivo per oltre 5 minuti. Utile per attivare email di follow-up.
message.receivedIl visitatore ha inviato un messaggio. Volume elevato — abbonati solo se hai un'esigenza specifica.
message.sentL'AI ha risposto a un visitatore. Volume elevato — abbonati solo se hai un'esigenza specifica.

Formato del payload

Ogni webhook invia un envelope JSON con gli stessi campi di primo livello. Il data l'oggetto varia in base al tipo di evento. Esempio per 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"
  }
}

Header della richiesta

Ogni richiesta include:

  • Content-Type: application/json
  • User-Agent: DBestChatBot-Webhook/1.0
  • X-DBestChatBot-Event: lead.captured — il nome dell'evento
  • X-DBestChatBot-Delivery: evt_abc123 — ID di consegna univoco, da usare per la deduplicazione
  • X-DBestChatBot-Signature: t=1747490400,v1=<hex_hmac> — firma di verifica

Verifica delle firme (consigliato)

Verifica sempre i payload dei webhook per assicurarti che provengano davvero da DBestChatBot. Il formato della firma è compatibile con Stripe: un timestamp Unix t e un digest esadecimale HMAC-SHA-256 v1, uniti da una virgola.

Algoritmo:

  1. Estrai t and v1 dall'intestazione
  2. Rifiuta se t è superiore a 5 minuti rispetto all'ora corrente (protezione replay)
  3. Calcola expected = HMAC_SHA256(signing_secret, "t.raw_request_body")
  4. Confronto a tempo costante expected with v1
  5. Se corrispondono, il payload è autentico. Altrimenti rifiuta.

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';

Nuovi tentativi e garanzie di consegna

Riproviamo fino a 5 volte with exponential backoff if your endpoint doesn't return a 2xx response within 30 seconds:

TentativoRitardo rispetto al precedente
1immediate
2+1 minuto
3+5 minuti
4+30 minuti
5+2 ore

Dopo il 5° tentativo fallito, la consegna viene contrassegnata come failed e interrompiamo i tentativi. Puoi vedere il log completo delle consegne (inclusi stato HTTP, messaggio di errore e numero di tentativi) nella pagina di dettaglio del webhook nella tua dashboard.

Restituisci sempre rapidamente uno stato 2xx. Se devi fare elaborazioni pesanti, rispondi prima con 200 ed elabora in modo asincrono.

Idempotenza

Ogni consegna ha un id campo (inviato anche come 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.

Allowlist IP

I webhook in uscita provengono dai nostri server di produzione su 15.204.199.41. Se usi una allowlist per IP, consenti questo indirizzo. Le firme sono comunque il percorso di verifica più affidabile — l'IP può essere falsificato, HMAC no (senza il segreto).

Per iniziare

  1. Vai a Webhooks nella tua dashboard
  2. Clicca Aggiungi endpoint — incolla il tuo URL, scegli gli eventi
  3. Copia il signing secret mostrato dopo la creazione
  4. Invia un evento di test per verificare che il tuo endpoint lo riceva e lo convalidi
  5. Osserva gli eventi reali scorrere mentre i visitatori usano i tuoi chatbot

Connessione a 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 nel tuo CRM, in Sheets o dove preferisci da lì.

HubSpot — guida completa

Questa è la configurazione più comune. Cattura ogni lead del chatbot come Contatto HubSpot:

  1. In Zapier, clicca Crea Zap → Trigger: Webhooks by Zapier → evento Catch Hook → continua. Zapier ti mostra un URL personalizzato come https://hooks.zapier.com/hooks/catch/12345/abc/
  2. In DBestChatBot, vai a Webhooks → Aggiungi endpoint. Paste the Zapier URL, name it "HubSpot via Zapier," subscribe to lead.captured, salva.
  3. Torna in Zapier: clicca Test trigger. Poi nella pagina webhook del tuo DBestChatChatBot, clicca Invia evento di test. Zapier dovrebbe ricevere un payload di esempio — l'esempio include data.visitor.name, data.visitor.email, data.visitor.phone, e qualsiasi campo personalizzato pre-chat che hai definito.
  4. In Zapier, aggiungi un Azione → HubSpot → evento Crea o aggiorna contatto. Autorizza il tuo account HubSpot.
  5. Mappa i campi:
    • HubSpot email ← Zapier data.visitor.email
    • HubSpot firstname ← Zapier data.visitor.name (separa nome/cognome se necessario)
    • 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 → inserisci manualmente in Lead or Subscriber
    • HubSpot website ← Zapier data.source_url
  6. Facoltativo ma consigliato: aggiungi una seconda azione → HubSpot → Crea nota su quel contatto con l'URL della trascrizione della chat data.transcript_url come corpo della nota. Il tuo team di vendita clicca il link e vede l'intera conversazione che ha portato alla cattura.
  7. Attiva lo Zap. Ogni futura lead.captured l'evento crea / aggiorna automaticamente un contatto HubSpot in pochi secondi.

Consiglio: 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.

Altri CRM: lo stesso schema funziona per Pipedrive (azione: Create Deal), Salesforce (azione: Create/Update Lead), Close (azione: Create Lead), monday.com (azione: Create Item) e Airtable (azione: Create Record). Il lato DBestChatBot è identico — basta indirizzare uno Zap diverso allo stesso URL del webhook.

FAQ

Why isn't my endpoint receiving events?

  • Verifica che il webhook sia active nella dashboard
  • Check you're subscribed to the right event type
  • Controlla il registro di consegna nella pagina di dettaglio del webhook per gli errori HTTP
  • Usa il Invia evento di test button to bypass real-world triggers

Come posso smettere temporaneamente di ricevere eventi?

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

Posso recuperare eventi più vecchi già svolti?

No, i webhook sono fire-and-forget. Per i dati storici, usa la dashboard Conversazioni esporta (CSV) o contattaci per un backfill una tantum.

Pronto a collegarlo?

Apri la dashboard dei Webhook