Aller au contenu
Documentation

Webhooks

Être prévenu par un appel à votre adresse quand une fiche change — s'abonner, vérifier la signature, répondre.

4 min de lecture Mise à jour le 12 novembre 2026

Un webhook appelle votre adresse quand un événement touche une fiche : un contact créé, un parcours terminé, un email ouvert… Plutôt que de relire une fiche pour voir si elle a changé, vous êtes prévenu. Le guide Recevoir un webhook montre un abonnement de bout en bout. Une application ouverte au nom d'un utilisateur — une application mobile, par exemple — reçoit plutôt les messages de ses conversations en temps réel.

S'abonner

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

{
  "Name": "Parcours vers notre CRM",
  "Url": "https://crm.example.com/hooks/parcours",
  "RecordTypeName": "Transaction",
  "Events": [20],
  "Scope": 0
}
  • RecordTypeName : le type de fiche écouté ; GET https://staging-api.docage.com/Webhooks/Catalog liste les types possibles et les événements de chacun.
  • Events : un ou plusieurs événements — 1 création, 2 modification, 0 suppression (mise à la corbeille comprise), 3 changement d'état (une restauration depuis la corbeille, un blocage…), 20 changement de statut d'un parcours, 30 changement de statut d'un email ; 10 à 12 pour ce qu'on range dans un classeur ou qu'on en retire.
  • Scope : 0 toutes les fiches du type, 1 les fiches tirées d'un modèle, 2 une seule fiche ; ScopeRecordId désigne le modèle ou la fiche.
  • WatchedFields restreint une modification aux champs qui comptent ([{ "FieldName": "SignatureStatus", "ToValue": "Done" }]) ; Condition, un filtre de liste écrit en texte JSON, à certaines fiches — voir Être prévenu quand un parcours est signé.
  • PayloadMode : 0 la charge complète (d'office) ; 1 la charge légère, sans la fiche — voir ci-dessous.
  • L'adresse est en HTTPS.

Le webhook ne reçoit que ce que son auteur voit : la fiche envoyée est projetée avec ses droits.

Ce que vous recevez

Un POST à votre adresse, en JSON. En charge complète (PayloadMode à 0, d'office), l'enveloppe porte la fiche :

JSON
{
  "id": "0f7c2a1e-0000-4000-8000-000000000091",
  "type": "Transaction.TransactionStatusChange",
  "timestamp": "2026-11-04T09:12:05.000Z",
  "webhook": { "id": "6a1b2c3d-0000-4000-8000-000000000090", "name": "Parcours vers notre CRM" },
  "organizationId": "5c6d7e8f-0000-4000-8000-000000000042",
  "entity": { "type": "Transaction", "id": "cccccccc-0000-4000-8000-000000000003", "name": "Contrat de prestation" },
  "changes": { "GlobalStatus": { "from": "Active", "to": "Done" } },
  "data": { "Id": "cccccccc-0000-4000-8000-000000000003", "GlobalStatus": 3 }
}

changes dit les propriétés modifiées, de l'ancienne valeur à la nouvelle, en texte — une énumération par son nom (Active, Done) ; data est la fiche, telle que l'API la rend, ses énumérations en nombres (abrégée ici).

En charge légère (PayloadMode à 1), l'enveloppe est la même, sans la fiche : data vaut null.

JSON
{
  "id": "0f7c2a1e-0000-4000-8000-000000000092",
  "type": "Transaction.TransactionStatusChange",
  "timestamp": "2026-11-04T09:12:05.000Z",
  "webhook": { "id": "6a1b2c3d-0000-4000-8000-000000000093", "name": "Parcours vers notre CRM, charge légère" },
  "organizationId": "5c6d7e8f-0000-4000-8000-000000000042",
  "entity": { "type": "Transaction", "id": "cccccccc-0000-4000-8000-000000000003", "name": "Contrat de prestation" },
  "changes": { "GlobalStatus": { "from": "Active", "to": "Done" } },
  "data": null
}

Relisez alors la fiche par son identifiant, entity.id :

GET https://staging-api.docage.com/Transactions/cccccccc-0000-4000-8000-000000000003
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…

Vous lisez ainsi la fiche telle qu'elle est au moment où vous la traitez, avec les droits de votre jeton plutôt qu'avec ceux de l'auteur du webhook ; une réponse null dit que ce jeton ne la voit pas, ou qu'elle n'existe plus. Une suppression, mise à la corbeille comprise, arrive toujours sans data, quel que soit le mode.

La référence de l'API décrit chacun de ces appels, type de fiche par type de fiche : les types d'événement qu'il peut porter, l'enveloppe et la fiche, typée. Ils sont dans la section webhooks de son document, https://staging-api.docage.com/openapi/v2-fr.json, et chacun dans le document du contrôleur de sa fiche, comme https://staging-api.docage.com/openapi/v2-fr/Contacts.json. Dans la référence, chacun paraît dans le groupe de sa fiche : « Être prévenu des changements des contacts ».

Vérifier la signature

Chaque appel porte trois en-têtes, selon la spécification Standard Webhooks :

  • webhook-id : l'identifiant de l'envoi, le même d'une tentative à l'autre ;
  • webhook-timestamp : l'heure de la tentative, en secondes Unix ;
  • webhook-signature : v1, suivi de la signature, en base64.

Il porte aussi webhook-attempt, le numéro de la tentative à partir de 1, et User-Agent: StandardWebhooks/1.0. Un webhook à jeton partagé envoie en plus Authorization: Bearer suivi de son jeton ; ses en-têtes personnalisés s'ajoutent à l'appel.

La signature est un HMAC-SHA256 de {webhook-id}.{webhook-timestamp}.{corps}, le corps tel que reçu, octet pour octet. Sa clé est le secret du webhook (whsec_…, à lire par POST https://staging-api.docage.com/Webhooks/{id}/Secret/Reveal), sans son préfixe, décodé du base64. Refusez un appel dont la signature ne se vérifie pas, ou dont l'heure s'écarte de plus de cinq minutes de la vôtre. Les bibliothèques Standard Webhooks font tout cela en une ligne.

Après un renouvellement du secret (POST https://staging-api.docage.com/Webhooks/{id}/Secret/Rotate), l'ancien signe encore 24 heures : webhook-signature porte alors deux signatures, séparées par une espace ; acceptez la première qui se vérifie.

Répondre

Répondez vite, par un code 2xx, et traitez ensuite : sans réponse en 20 secondes, la tentative est un échec, comme tout autre code :

  • l'envoi est retenté, à intervalles croissants : dix tentatives en tout, sur près de quatre jours ; un 429 avec Retry-After est respecté ;
  • une redirection (3xx) est un échec, jamais suivie ;
  • 410 met le webhook en panne aussitôt, comme 72 heures d'échecs continus : ses envois sont retenus, son auteur est prévenu, et POST https://staging-api.docage.com/Webhooks/{id}/Reactivate le remet en service — avec { "ReplayHeld": true }, ses envois retenus repartent ; sans lui, ils sont annulés.

Un envoi peut arriver deux fois : ignorez un webhook-id déjà traité. L'historique des envois d'un webhook se lit par GET https://staging-api.docage.com/Webhooks/{id}/Deliveries ; POST https://staging-api.docage.com/Webhooks/{id}/Test en tente un tout de suite.