Webhooks für neue Leads
Ein Webhook sendet jeden neuen Lead aus Ihren Chat-Kanälen, etwa Website-Chat, Messenger und Instagram, sofort an eine andere App: Ihr CRM, Zapier, Make, n8n oder Ihren eigenen Code. KnowStack schickt dafür einen signierten HTTPS-POST mit den Kontaktdaten des Leads und dem Gesprächsverlauf bis zu diesem Moment.
Lead-Webhooks sind in Business, Enterprise und der kostenlosen Testphase enthalten. Einrichten können sie alle, deren Rolle Benutzer verwalten darf, zum Beispiel Company Admin.
Webhook hinzufügen
- Kopieren Sie die Webhook-Adresse aus der App, die die Leads erhalten soll. Sie muss mit https:// beginnen.
- Öffnen Sie in KnowStack die Einstellungen, wählen Sie „Integrationen“ und gehen Sie zu „Leads an Ihr CRM senden“.
- Geben Sie unter „Webhook hinzufügen“ im Feld „Name“ einen Namen ein, den Sie wiedererkennen, fügen Sie die Adresse im Feld „Webhook-Adresse“ ein und klicken Sie auf „Webhook hinzufügen“.
- Kopieren Sie den angezeigten Signaturschlüssel. Er beginnt mit whsec_ und wird nur einmal angezeigt. Klicken Sie dann auf „Ich habe ihn gespeichert“.
- Öffnen Sie das Menü des Webhooks und klicken Sie auf „Test senden“. Das Ergebnis erscheint sofort und im „Zustellprotokoll“.
Gesendet werden nur Leads, die nach dem Hinzufügen des Webhooks erfasst werden; ältere Leads bleiben in KnowStack. Sie können mehrere Webhooks anlegen, und jeder neue Lead geht an alle aktiven.
Die Adresse muss öffentlich sein: nur https, auf dem Standardport, ohne Benutzername oder Passwort. Adressen in einem privaten oder lokalen Netz werden abgelehnt, auch wenn ein öffentlicher Name später auf eines zeigt. Weiterleitungen werden nicht verfolgt, fügen Sie also die endgültige Adresse ein.
Wann Anfragen gesendet werden
| Ereignis | Wann | Inhalt |
|---|---|---|
| lead.created | Ein Chat erfasst einen neuen Lead | Der Lead und das Gespräch bis zu diesem Moment |
| lead.updated | Name, E-Mail oder Telefon kommen später im selben Lead hinzu | Die aktuellen Daten des Leads und eine Liste changed mit den neuen Feldern, ohne das Gespräch |
| test | Sie klicken auf „Test senden“ | Ein Beispiel-Lead mit der id 0 und ein kurzes Beispielgespräch |
Nachrichten, die nach dem Anlegen des Leads geschrieben werden, werden nie gesendet. Eine lead.updated-Anfrage geht erst raus, nachdem lead.created angenommen wurde, und nur wenn ein Feld von leer zu ausgefüllt wechselt.
Header der Anfrage
| Header | Wert |
|---|---|
| Content-Type | application/json |
| User-Agent | LeadWebhook/1.0 |
| X-Webhook-Event | lead.created, lead.updated oder test |
| X-Webhook-Delivery | Die Zustellungs-ID. Bei einem erneuten Versuch derselben Zustellung bleibt sie gleich, nutzen Sie sie also, um Duplikate zu ignorieren |
| X-Webhook-Timestamp | Zeitpunkt der Signatur in Unix-Sekunden |
| X-Webhook-Signature | v1= gefolgt vom hexadezimalen HMAC-SHA256 aus Zeitstempel, einem Punkt und dem unveränderten Body, berechnet mit Ihrem Signaturschlüssel |
Payload (Version 1)
Der Body ist JSON in UTF-8, wird ohne Zeilenumbrüche gesendet und hier formatiert gezeigt. Werte in spitzen Klammern stehen für Ihre eigenen: Der Produktname ist KnowStack, die Adresse ist die, unter der Sie sich anmelden. Eine lead.created-Anfrage:
{
"version": 1,
"event": "lead.created",
"deliveryId": "4821",
"occurredAt": "2026-01-15T10:03:12.000Z",
"lead": {
"id": 1375,
"name": "Anna Novak",
"email": "[email protected]",
"phone": null,
"channel": "web_chat",
"channelLabel": "Website chat",
"source": "<product name> · Website chat",
"question": "Do you have availability next week?",
"firstPageUrl": "https://example.com/pricing",
"locale": "en",
"capturedAt": "2026-01-15T10:02:40.000Z",
"conversationUrl": "https://<your app address>/dashboard/channels/website-chat?conversation=812"
},
"transcript": [
{ "from": "customer", "text": "Hi, do you have availability next week?", "at": "2026-01-15T10:00:05.000Z" },
{ "from": "ai", "text": "Yes, we do. Could I take your email so the team can confirm a time?", "at": "2026-01-15T10:00:09.000Z" },
{ "from": "customer", "text": "Sure, [email protected]", "at": "2026-01-15T10:02:40.000Z" }
],
"transcriptIncomplete": false
}
| Feld | Bedeutung |
|---|---|
| version | In diesem Format immer 1. Eine Änderung, die Ihren Code brechen könnte, bekommt eine neue Nummer |
| event, deliveryId | Dieselben Werte wie in den Headern X-Webhook-Event und X-Webhook-Delivery |
| occurredAt | Zeitpunkt, zu dem die Anfrage erstellt wurde, im Format ISO 8601 (UTC) |
| lead.id | Die ID des Leads in KnowStack. lead.updated trägt dieselbe ID, so finden Sie den angelegten Datensatz wieder |
| lead.name, lead.email, lead.phone | Kontaktdaten. Jedes dieser Felder kann null sein |
| lead.channel | Wo der Chat stattfand: derzeit web_chat, messenger oder instagram. Mit neuen Kanälen kommen neue Werte hinzu, akzeptieren Sie also beliebigen Text |
| lead.channelLabel, lead.source | Der Anzeigename des Kanals und eine fertige Lead-Quelle wie "KnowStack · Instagram", in der Sprache der Person, die den Webhook hinzugefügt hat |
| lead.question | Die Frage, die der Kunde beim Erfassen des Leads gestellt hat, oder null |
| lead.firstPageUrl, lead.locale | Die Seite, auf der ein Website-Chat begann, und die Sprache des Besuchers. Bei anderen Kanälen meist null |
| lead.capturedAt | Zeitpunkt, zu dem die Kontaktdaten hinterlassen wurden |
| lead.conversationUrl | Ein Link zum Gespräch in KnowStack, für alle, die sich bei Ihrem Unternehmen anmelden können |
| transcript | Das Gespräch bis zum Anlegen des Leads, älteste Nachricht zuerst, höchstens 500 Nachrichten. Jede hat from (customer, ai oder team), text und at |
| transcriptIncomplete | true, wenn ältere Nachrichten gemäß Ihren Aufbewahrungseinstellungen bereits gelöscht wurden. Diese Nachrichten haben text null und purged true |
Ein lead.updated-Body hat dieselben Felder version, event, deliveryId, occurredAt und lead, mit den aktuellen Werten des Leads. Statt des Gesprächs enthält er changed, die Liste der seit der letzten Anfrage ausgefüllten Felder, zum Beispiel ["phone"].
Signatur prüfen
- Lesen Sie den unveränderten Body der Anfrage, bevor Sie ihn als JSON parsen.
- Verbinden Sie den Wert von X-Webhook-Timestamp, einen Punkt und den unveränderten Body.
- Berechnen Sie den HMAC-SHA256 dieses Textes mit Ihrem Signaturschlüssel, dem vollständigen Wert einschließlich whsec_, und schreiben Sie ihn hexadezimal.
- Vergleichen Sie v1= plus diesen Hexwert mit X-Webhook-Signature, mit einem Vergleich in konstanter Zeit.
- Lehnen Sie die Anfrage ab, wenn der Zeitstempel mehr als 5 Minuten von Ihrer Uhr abweicht. So kann niemand eine alte Anfrage erneut abspielen.
Ein Beispiel für Node.js mit Express:
const crypto = require('crypto');
const express = require('express');
const SECRET = process.env.LEAD_WEBHOOK_SECRET; // whsec_...
const app = express();
// Keep the body raw: the signature covers the exact bytes that were sent.
app.post('/leads', express.raw({ type: 'application/json' }), (req, res) => {
const timestamp = req.get('X-Webhook-Timestamp') || '';
const received = req.get('X-Webhook-Signature') || '';
const expected = 'v1=' + crypto
.createHmac('sha256', SECRET)
.update(timestamp + '.' + req.body)
.digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
const valid = received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!fresh || !valid) return res.status(401).end();
const body = JSON.parse(req.body);
// req.get('X-Webhook-Delivery') identifies the delivery: skip it if you
// have already handled it.
console.log(body.event, body.lead.id);
res.status(204).end();
});
app.listen(3000);
Zum Prüfen Ihres Codes: Der Schlüssel whsec_test, der Zeitstempel 1761559200 und der Body {"a":1} ergeben die Signatur v1=ed347bcd87edf5b36afc10e41346740621d7f3c26b13ee1a4cc1eb7cddd0786f.
Antworten und erneute Versuche
| Ihre Antwort | Was passiert |
|---|---|
| 2xx | Zugestellt |
| 408, 429, 5xx, eine Zeitüberschreitung oder ein Netzwerkfehler | Wird in wachsenden Abständen etwa 24 Stunden lang erneut versucht, danach als fehlgeschlagen markiert. Retry-After bei einer 429 wird beachtet, bis zu einer Stunde |
| 410 | Der Webhook wechselt sofort auf „Prüfen nötig“ |
| 401, 403 oder 404 dreimal ohne erfolgreiche Zustellung dazwischen | Der Webhook wechselt auf „Prüfen nötig“ |
| Jeder andere Code, auch eine Weiterleitung | Als fehlgeschlagen markiert, kein erneuter Versuch |
Antworten Sie innerhalb von 10 Sekunden, sonst zählt der Versuch als Zeitüberschreitung. Von Ihrer Antwort werden nur die ersten 64 KB gelesen. Antworten Sie zuerst und erledigen Sie langsame Arbeit danach.
Wenn ein Webhook Aufmerksamkeit braucht
Solange ein Webhook „Prüfen nötig“ oder „Pausiert“ zeigt, warten neue Leads in der Warteschlange, statt verloren zu gehen. Hört ein Webhook auf zu arbeiten, erhalten alle, die Benutzer verwalten, eine einzige Meldung in der Benachrichtigungsglocke und, falls verbunden, in Telegram. Beheben Sie das Problem in der empfangenden App oder korrigieren Sie die Adresse über „Bearbeiten“, oder klicken Sie auf „Fortsetzen“, wenn die Adresse stimmte. Danach wird wieder gesendet, beginnend mit den wartenden Leads.
„Zustellprotokoll“ im Menü des Webhooks zeigt die letzten 50 Anfragen mit Ergebnis und Antwortcode. Klicken Sie bei einer fehlgeschlagenen auf „Erneut senden“, um sie mit derselben Zustellungs-ID noch einmal zu senden. Im Tab „Leads“ jedes Chat-Kanals zeigt eine Markierung, ob ein Lead Ihr CRM erreicht hat; für einen nicht gesendeten Lead wählen Sie „Erneut ans CRM senden“ im Menü seiner Zeile. Schlagen Leads weiter fehl, während ein Webhook aktiv bleibt, zeigt seine Zeile „Letzte Zustellungen fehlgeschlagen“, und wer Benutzer verwaltet, erhält höchstens einmal am Tag eine Benachrichtigung.
Signaturschlüssel
Wenn der Schlüssel in falsche Hände geraten ist, wählen Sie „Neuer Signaturschlüssel“ im Menü des Webhooks. Der alte Schlüssel funktioniert sofort nicht mehr, tragen Sie den neuen also gleich in der empfangenden App ein.
Wechselt Ihr Unternehmen in einen Plan ohne Lead-Webhooks, werden neue Leads nicht gesendet. Leads, die in dieser Zeit für einen aktiven Webhook eingehen, werden übersprungen und nach einem Upgrade nicht von selbst gesendet; nach dem Upgrade können Sie jeden mit „Erneut ans CRM senden“ senden. Leads, die bei einem pausierten Webhook oder einem mit „Prüfen nötig“ warten, bleiben in der Warteschlange und gehen raus, sobald Sie upgraden und ihn fortsetzen. Ihre Webhooks bleiben in der Liste, und Sie können sie weiterhin pausieren oder löschen.