Aller au contenu
Documentation

Recevoir un webhook

S'abonner aux changements de statut des parcours, vérifier chaque appel, et répondre sans le perdre.

2 min de lecture Mise à jour le 9 novembre 2026

Exemple : votre CRM veut savoir quand un parcours se termine. Les règles détaillées sont dans Webhooks.

1S'abonner

POST https://staging-api.docage.com/Webhooks
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json

{
  "Name": "Parcours terminés vers le CRM",
  "Url": "https://crm.example.com/hooks/parcours",
  "RecordTypeName": "Transaction",
  "Events": [20],
  "Scope": 0,
  "Condition": "{\"OperatorType\":\"And\",\"Operands\":[{\"PropertyName\":\"GlobalStatus\",\"Comparison\":\"=\",\"Value\":\"3\"}]}"
}

La réponse est l'identifiant du webhook. L'événement 20 est le changement de statut d'un parcours : son envoi, sa fin, son refus… ; Condition, un filtre écrit en texte JSON, ne retient que la fin (GlobalStatus à 3). GET https://staging-api.docage.com/Webhooks/Catalog liste les types de fiches et leurs événements. Pour un parcours signé, ou ceux d'un seul modèle, voir Être prévenu quand un parcours est signé.

2Lire le secret de signature

POST https://staging-api.docage.com/Webhooks/6a1b2c3d-0000-4000-8000-000000000090/Secret/Reveal
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…

La réponse porte le secret dans Value (whsec_…) : gardez-le dans la configuration de votre récepteur, comme un mot de passe.

3Vérifier chaque appel

Votre adresse reçoit un POST JSON, avec les en-têtes webhook-id, webhook-timestamp et webhook-signature. En Node.js :

JavaScript
const crypto = require('node:crypto');

function verifier(corpsBrut, entetes, secret) {
  const id = entetes['webhook-id'];
  const horodatage = entetes['webhook-timestamp'];
  if (Math.abs(Date.now() / 1000 - Number(horodatage)) > 300) return false;
  const cle = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
  const attendue = crypto.createHmac('sha256', cle).update(`${id}.${horodatage}.${corpsBrut}`).digest('base64');
  return entetes['webhook-signature'].split(' ').some(s => {
    const recue = s.replace(/^v1,/, '');
    return recue.length === attendue.length && crypto.timingSafeEqual(Buffer.from(recue), Buffer.from(attendue));
  });
}

Le corps se vérifie tel que reçu, avant toute lecture du JSON : un corps relu puis réécrit ne donne plus la même signature.

4Répondre, puis traiter

Répondez 200 dès la signature vérifiée, et traitez ensuite. Dans le corps, type vaut Transaction.TransactionStatusChange, entity.id désigne le parcours, et changes.GlobalStatus donne l'ancien statut et le nouveau, par leur nom : Done est « Terminé » (data.GlobalStatus le donne en nombre, 3). Retenez le webhook-id : un envoi qui vous parvient deux fois se reconnaît à lui.

5Essayer, et suivre les envois

  • POST https://staging-api.docage.com/Webhooks/{id}/Test envoie un appel d'essai tout de suite, et rend son résultat.
  • GET https://staging-api.docage.com/Webhooks/{id}/Deliveries liste les envois du webhook : leur statut, leurs tentatives, le code que votre adresse a rendu.
  • Un webhook dont l'adresse échoue trop longtemps est mis en panne : ses envois sont retenus et son auteur est prévenu. POST https://staging-api.docage.com/Webhooks/{id}/Reactivate le remet en service ; avec { "ReplayHeld": true }, les envois retenus repartent — sans lui, ils sont annulés.