All docs Referenz

API + Webhooks

Erhalte Echtzeit-HTTPS-POSTs an dein CRM, Slack, Zapier, n8n oder jedes andere System, wenn Ereignisse in deinen Chatbots auftreten.

Ausgehende Webhooks

HMAC SHA-256 signiert

Bis zu 5 Wiederholungsversuche mit Backoff

Overview

DBestChatBot sendet ausgehende Webhooks, wenn auf deinen Chatbots wichtige Ereignisse eintreten (ein Lead wird erfasst, eine Konversation beginnt oder endet, eine Nachricht wird gesendet oder empfangen). Du konfigurierst eine Ziel-URL im Dashboard, und wir POSTen innerhalb von Sekunden nach jedem Ereignis einen JSON-Umschlag dorthin.

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

Termine

Jeder Webhook abonniert einen oder mehrere dieser Ereignistypen:

TerminWann er ausgelöst wird
lead.capturedEin Besucher sendet das Pre-Chat-Formular ab, ODER eine eingehende WhatsApp-Nachricht startet eine Unterhaltung (wir haben immer die Telefonnummer). Empfohlen für die CRM-Anbindung.
conversation.startedEin neues Gespräch beginnt. Nützlich für Marketing-Analysen oder um Follow-up-Workflows sofort zu starten.
conversation.endedBesucher schließt den Chat oder er wird 5+ Minuten inaktiv. Gut zum Auslösen von Follow-up-E-Mails.
message.receivedBesucher hat eine Nachricht gesendet. Hohes Volumen — abonnieren Sie nur, wenn Sie einen konkreten Bedarf haben.
message.sentDie KI hat einem Besucher geantwortet. Hohes Volumen — abonnieren Sie nur, wenn Sie einen konkreten Bedarf haben.

Payload-Format

Jeder Webhook sendet einen JSON-Umschlag mit denselben Feldern auf oberster Ebene. Die data Objekt variiert je nach Ereignistyp. Beispiel für 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"
  }
}

Anfrage-Header

Jede Anfrage enthält:

  • Content-Type: application/json
  • User-Agent: DBestChatBot-Webhook/1.0
  • X-DBestChatBot-Event: lead.captured — der Ereignisname
  • X-DBestChatBot-Delivery: evt_abc123 — eindeutige Zustellungs-ID, zur Deduplizierung verwenden
  • X-DBestChatBot-Signature: t=1747490400,v1=<hex_hmac> — verification signature

Signaturen überprüfen (empfohlen)

Verifiziere Webhook-Payloads immer, um sicherzustellen, dass sie tatsächlich von DBestChatBot stammen. Das Signaturformat ist Stripe-kompatibel: ein Unix-Zeitstempel t und einen HMAC-SHA-256-Hex-Digest v1, durch ein Komma getrennt.

Algorithmus:

  1. Extrahieren t and v1 aus der Kopfzeile
  2. Ablehnen, wenn t liegt mehr als 5 Minuten von der aktuellen Zeit entfernt (Replay-Schutz)
  3. Berechnen expected = HMAC_SHA256(signing_secret, "t.raw_request_body")
  4. Vergleich in konstanter Zeit expected with v1
  5. Wenn sie übereinstimmen, ist die Payload authentisch. Andernfalls ablehnen.

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

Wiederholungen und Zustellgarantien

Wir versuchen es bis zu 5-mal with exponential backoff if your endpoint doesn't return a 2xx response within 30 seconds:

VersuchVerzögerung ab dem vorherigen
1immediate
2+1 Minute
3+5 Minuten
4+30 Minuten
5+2 Stunden

Nach dem 5. fehlgeschlagenen Versuch wird die Zustellung markiert als failed und wir beenden die Wiederholungsversuche. Das vollständige Zustellprotokoll (einschließlich HTTP-Status, Fehlermeldung und Anzahl der Versuche) finden Sie auf der Webhook-Detailseite in Ihrem Dashboard.

Immer schnell einen 2xx-Status zurückgeben. Wenn du eine aufwändige Verarbeitung durchführen musst, bestätige zuerst mit 200 und verarbeite asynchron.

Idempotenz

Jede Zustellung hat eine eindeutige id Feld (auch gesendet als 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.

IP-Allowlisting

Ausgehende Webhooks stammen von unseren Produktionsservern unter 15.204.199.41. Wenn du per IP allowlistest, erlaube diese Adresse. Signaturen sind jedoch der zuverlässigere Verifizierungsweg — IP kann gefälscht werden, HMAC nicht (ohne das Geheimnis).

Erste Schritte

  1. Gehe zu Webhooks in deinem Dashboard
  2. Klicken Endpoint hinzufügen — URL einfügen, Ereignisse auswählen
  3. Kopieren Sie den Signaturgeheimnis nach der Erstellung angezeigt
  4. Sende ein Test-Event, um zu prüfen, ob dein Endpoint es empfängt und validiert
  5. Beobachten Sie, wie echte Ereignisse durchlaufen, während Besucher Ihre Chatbots nutzen

Verbindung zu Zapier / Make / n8n wird hergestellt

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 in dein CRM, Sheets oder von dort aus wohin auch immer.

HubSpot — vollständige Anleitung

Dies ist die häufigste Einrichtung. Erfasst jeden Chatbot-Lead als HubSpot-Kontakt:

  1. Klicken Sie in Zapier auf Zap erstellen → Trigger: Webhooks by Zapier → event Catch Hook → continue. Zapier shows you a custom URL like https://hooks.zapier.com/hooks/catch/12345/abc/
  2. Gehen Sie in DBestChatBot zu Webhooks → Endpoint hinzufügen. Paste the Zapier URL, name it "HubSpot via Zapier," subscribe to lead.captured, speichern.
  3. Zurück in Zapier: klicken Test-TriggerKlicke dann auf deiner DBestChatBot-Webhook-Seite auf Testevent sendenZapier sollte eine Beispiel-Payload erhalten — das Beispiel enthält data.visitor.name, data.visitor.email, data.visitor.phone, and any custom pre-chat fields you defined.
  4. Fügen Sie in Zapier eine Aktion → HubSpot → event Kontakt erstellen oder aktualisieren. Autorisiere dein HubSpot-Konto.
  5. Ordnen Sie die Felder zu:
    • HubSpot email ← Zapier data.visitor.email
    • HubSpot firstname ← Zapier data.visitor.name (split first/last if you need)
    • 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 → hardcode to Lead or Abonnent
    • HubSpot website ← Zapier data.source_url
  6. Optional, aber empfohlen: zweite Aktion hinzufügen → HubSpot → Notiz erstellen zu diesem Kontakt mit der URL des Chat-Transkripts data.transcript_url als Notiztext. Dein Vertriebsteam klickt auf den Link und sieht das gesamte Gespräch, das zur Erfassung geführt hat.
  7. Aktivieren Sie den Zap. Jede künftige lead.captured event auto-creates / updates a HubSpot Contact within seconds.

Profi-Tipp: 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.

Andere CRMs: dasselbe Muster funktioniert für Pipedrive (Aktion: Create Deal), Salesforce (Aktion: Create/Update Lead), Close (Aktion: Create Lead), monday.com (Aktion: Create Item) und Airtable (Aktion: Create Record). Die DBestChatBot-Seite ist identisch — richte einfach einen anderen Zap auf dieselbe Webhook-URL.

FAQ

Why isn't my endpoint receiving events?

  • Prüfen Sie, ob der Webhook active im Dashboard
  • Check you're subscribed to the right event type
  • Prüfen Sie das Zustellungsprotokoll auf der Webhook-Detailseite auf HTTP-Fehler
  • Verwende die Testevent senden button to bypass real-world triggers

Wie pausiere ich den Empfang von Events vorübergehend?

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

Kann ich ältere Ereignisse abrufen, die bereits stattgefunden haben?

Nein, Webhooks sind Fire-and-Forget. Für historische Daten nutze das Dashboard Konversationen exportiere (CSV) oder kontaktiere uns wegen eines einmaligen Backfills.

Bereit, es zu verbinden?

Webhooks-Dashboard öffnen