Webhooks pour les nouveaux leads

Un webhook envoie chaque nouveau lead de vos canaux de chat, comme le chat du site, Messenger et Instagram, vers une autre application dès sa capture : votre CRM, Zapier, Make, n8n ou votre propre code. KnowStack effectue un POST HTTPS signé avec les coordonnées du lead et la conversation jusqu'à ce moment.

Les webhooks de leads sont inclus avec Business, Enterprise et l'essai gratuit. Vous pouvez les configurer si votre rôle permet de gérer les utilisateurs, par exemple Company Admin.

Ajouter un webhook

  1. Copiez l'adresse du webhook dans l'application qui doit recevoir les leads. Elle doit commencer par https://.
  2. Dans KnowStack, ouvrez les Paramètres, sélectionnez « Intégrations » et allez à « Envoyer les leads vers votre CRM ».
  3. Sous « Ajouter un webhook », saisissez dans « Nom » un nom facile à reconnaître, collez l'adresse dans « Adresse du webhook » et cliquez sur « Ajouter le webhook ».
  4. Copiez la clé de signature qui s'affiche. Elle commence par whsec_ et n'est affichée qu'une fois. Cliquez ensuite sur « Je l’ai enregistrée ».
  5. Ouvrez le menu du webhook et cliquez sur « Envoyer un test ». Le résultat s'affiche aussitôt et dans le « Journal des envois ».

Seuls les leads capturés après l'ajout du webhook sont envoyés ; les leads plus anciens restent dans KnowStack. Vous pouvez ajouter plusieurs webhooks, et chaque nouveau lead part vers tous ceux qui sont actifs.

L'adresse doit être publique : https uniquement, sur le port standard, sans nom d'utilisateur ni mot de passe. Les adresses d'un réseau privé ou local sont refusées, y compris lorsqu'un nom public finit par pointer vers l'une d'elles. Les redirections ne sont pas suivies : collez donc l'adresse finale.

Quand les requêtes sont envoyées

ÉvénementQuandContenu
lead.createdUn chat capture un nouveau leadLe lead et la conversation jusqu'à ce moment
lead.updatedUn nom, un e-mail ou un téléphone apparaît plus tard dans le même leadLes données actuelles du lead et une liste changed des nouveaux champs, sans la conversation
testVous cliquez sur « Envoyer un test »Un lead d'exemple avec l'id 0 et une courte conversation d'exemple

Les messages écrits après la création du lead ne sont jamais envoyés. Une requête lead.updated ne part qu'une fois lead.created accepté, et seulement quand un champ passe de vide à rempli.

En-têtes de la requête

En-têteValeur
Content-Typeapplication/json
User-AgentLeadWebhook/1.0
X-Webhook-Eventlead.created, lead.updated ou test
X-Webhook-DeliveryL'identifiant de l'envoi. Il reste le même quand l'envoi est retenté : servez-vous-en pour ignorer les doublons
X-Webhook-TimestampLe moment de la signature, en secondes Unix
X-Webhook-Signaturev1= suivi du HMAC-SHA256 en hexadécimal de l'horodatage, d'un point et du corps brut, calculé avec votre clé de signature

Contenu (version 1)

Le corps est du JSON en UTF-8, envoyé sans retours à la ligne et présenté ici mis en forme. Les valeurs entre chevrons désignent les vôtres : le nom du produit est KnowStack, et l'adresse est celle où vous vous connectez. Une requête lead.created :

{
  "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
}
ChampSignification
versionToujours 1 dans ce format. Un changement qui pourrait casser votre code recevra un nouveau numéro
event, deliveryIdLes mêmes valeurs que les en-têtes X-Webhook-Event et X-Webhook-Delivery
occurredAtLe moment où la requête a été construite, au format ISO 8601 (UTC)
lead.idL'identifiant du lead dans KnowStack. lead.updated porte le même identifiant, ce qui vous permet de retrouver la fiche créée
lead.name, lead.email, lead.phoneLes coordonnées. Chacune peut valoir null
lead.channelOù le chat a eu lieu : aujourd'hui web_chat, messenger ou instagram. De nouvelles valeurs apparaissent avec les nouveaux canaux : acceptez donc n'importe quel texte
lead.channelLabel, lead.sourceLe nom affiché du canal et une source de lead toute prête comme "KnowStack · Instagram", dans la langue de la personne qui a ajouté le webhook
lead.questionLa question posée par le client lors de la capture du lead, ou null
lead.firstPageUrl, lead.localeLa page où un chat du site a commencé et la langue du visiteur. Généralement null pour les autres canaux
lead.capturedAtLe moment où les coordonnées ont été laissées
lead.conversationUrlUn lien vers la conversation dans KnowStack, pour les personnes qui peuvent se connecter à votre entreprise
transcriptLa conversation jusqu'à la création du lead, du plus ancien au plus récent, 500 messages au plus. Chacun a from (customer, ai ou team), text et at
transcriptIncompletetrue quand des messages plus anciens ont déjà été supprimés selon vos réglages de conservation. Ces messages ont text à null et purged à true

Un corps lead.updated a les mêmes champs version, event, deliveryId, occurredAt et lead, avec les valeurs actuelles du lead. À la place de la conversation, il contient changed, la liste des champs remplis depuis la dernière requête, par exemple ["phone"].

Vérifier la signature

  1. Lisez le corps brut de la requête avant de l'analyser comme du JSON.
  2. Assemblez la valeur de X-Webhook-Timestamp, un point et le corps brut.
  3. Calculez le HMAC-SHA256 de ce texte avec votre clé de signature, la valeur complète avec whsec_, et écrivez-le en hexadécimal.
  4. Comparez v1= suivi de cette valeur à X-Webhook-Signature, avec une comparaison en temps constant.
  5. Refusez la requête si l'horodatage s'écarte de plus de 5 minutes de votre horloge. Cela empêche de rejouer une ancienne requête.

Un exemple pour Node.js avec 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);

Pour tester votre code : la clé whsec_test, l'horodatage 1761559200 et le corps {"a":1} donnent la signature v1=ed347bcd87edf5b36afc10e41346740621d7f3c26b13ee1a4cc1eb7cddd0786f.

Réponses et nouvelles tentatives

Votre réponseCe qui se passe
2xxLivré
408, 429, 5xx, un délai dépassé ou une erreur réseauNouvelles tentatives à intervalles croissants pendant environ 24 heures, puis marqué en échec. Un Retry-After sur une 429 est respecté, jusqu'à une heure
410Le webhook passe aussitôt à « À vérifier »
401, 403 ou 404 trois fois sans livraison réussie entre-tempsLe webhook passe à « À vérifier »
Tout autre code, y compris une redirectionMarqué en échec, sans nouvelle tentative

Répondez en moins de 10 secondes, sinon la tentative compte comme un délai dépassé. Seuls les 64 premiers Ko de votre réponse sont lus. Répondez d'abord et faites le travail long ensuite.

Quand un webhook est à vérifier

Tant qu'un webhook affiche « À vérifier » ou « En pause », les nouveaux leads attendent dans la file au lieu d'être perdus. Quand un webhook s'arrête, les personnes qui gèrent les utilisateurs reçoivent une seule alerte dans la cloche de notifications, et sur Telegram si elles l'ont connecté. Corrigez l'application réceptrice ou l'adresse avec « Modifier », ou cliquez sur « Reprendre » si l'adresse était bonne. L'envoi reprend, en commençant par les leads en attente.

Le « Journal des envois » du menu du webhook montre les 50 dernières requêtes avec leur résultat et leur code de réponse. Cliquez sur « Réessayer » sur une requête en échec pour la renvoyer avec le même identifiant d'envoi. Dans l'onglet « Leads » de chaque canal de chat, un repère indique si un lead a atteint votre CRM ; pour un lead non envoyé, choisissez « Renvoyer au CRM » dans le menu de sa ligne. Si des leads continuent d'échouer alors que le webhook reste actif, sa ligne indique « Les derniers envois ont échoué » et les personnes qui gèrent les utilisateurs reçoivent une alerte, au plus une fois par jour.

Clé de signature

Si la clé a fuité, choisissez « Nouvelle clé de signature » dans le menu du webhook. L'ancienne clé cesse aussitôt de fonctionner : saisissez tout de suite la nouvelle dans l'application réceptrice.

Si votre entreprise passe à un plan sans webhooks de leads, les nouveaux leads ne sont pas envoyés. Les leads arrivés entre-temps pour un webhook actif sont ignorés et ne partent pas d'eux-mêmes après une mise à niveau ; une fois la mise à niveau faite, vous pouvez envoyer chacun avec « Renvoyer au CRM ». Les leads en attente sur un webhook en pause ou « À vérifier » restent dans la file et partent après la mise à niveau, quand vous le réactivez. Vos webhooks restent dans la liste, et vous pouvez toujours les mettre en pause ou les supprimer.