Webhooks
Recevez des événements de signature en temps réel via HTTP avec des livraisons signées HMAC, des tentatives automatiques et un filet de sécurité de relecture depuis la console.
Signature de demande SHA-256
Per-webhook secret, envoyé comme X-Endorsed-Signature
Délai de livraison écoulé
Retournez 2xx dans la fenêtre ou la tentative échoue
Réessaye après la première tentative
60s, 5m, 15m, 1h, puis 6h
Depuis la console développeur
Inspectez chaque tentative et rejouez des événements individuels
Ce que vous pouvez faire avec les événements webhook
Chaque transition significative du cycle de vie émet un événement typé. Utilisez-les pour mettre à jour vos propres enregistrements sans interrogation.
Déclencher des actions en aval
Lorsqu''une enveloppe est entièrement signée, mettez à jour votre CRM, libérez une ressource provisionnée ou envoyez une confirmation dans votre propre produit, le tout sans interroger le API.
Synchroniser l''état du document
Gardez votre base de données synchronisée avec le cycle de vie de signature : envoyé, ouvert, signé, refusé, expiré, annulé. Un événement par transition, aucune boucle d''interrogation requise.
Journalisation d''audit et de conformité
Alimentez les événements webhook dans votre propre magasin d''audit. Les identifiants de corrélation relient chaque événement à la demande API d''origine pour une traçabilité complète.
Rejouer les livraisons ayant échoué
Les événements qui épuisent l''échelle de nouvelle tentative atterrissent dans une file d''attente de lettres mortes que vous pouvez inspecter dans la console du développeur et rejouer intentionnellement.
Webhook référence de l''événement
Enregistrez un webhook, choisissez les événements que vous souhaitez et EndorsedSign fournit une charge utile JSON avec `event`, `tenantId`, `timestamp` et `data`. Les noms d''événements correspondent aux chaînes que vous envoyez dans l''appel de création webhook.
| Type d''événement | Quand il se déclenche | Champs clés « données » |
|---|---|---|
| document.created | Vous téléchargez un document via le API | ID document, ID client, ID Document externe |
| document.sent | Lien de signature envoyé au premier destinataire | documentId, customerId, canal |
| document.viewed | Signer ouvre le lien de signature | documentId, signataireEmail, consulté à |
| document.signed | Le signataire individuel termine son étape | documentId, signataireEmail, signéAt |
| document.completed | Toutes les parties ont signé | documentId, terminé à, downloadUrl |
| document.declined | Un signataire refuse explicitement | documentId, signataireEmail, raison |
| document.expired | Le document atteint sa date d''expiration sans être signé | documentId, expiré à |
| signing.started | Le jeton de session de signature est utilisé | documentId, sessionId, signataireEmail |
| signing.completed | Fin de la session de signature (signée ou refusée) | documentId, sessionId, résultat |
| client.créé / .mis à jour / .supprimé | Vous faites muter une fiche client | ID client, ID client externe |
| modèle.créé / .mis à jour | Vous modifiez un modèle | templateId, nom |
La liste complète se trouve dans le backend `WEBHOOK_EVENTS`. Ajoutez ou restreignez les abonnements par webhook — le pipeline de livraison diffuse un appel HTTP par point de terminaison enregistré.
Vérification des signatures webhook (Node.js)
Chaque livraison comprend un en-tête `X-Endorsed-Signature` : `t={unix_seconds},v1={hex}`. `v1` est HMAC-SHA256 de `{timestamp}.{rawBody}` en utilisant le secret renvoyé lors de la création du webhook. Rejeter les horodatages en dehors de ±5 minutes. `X-Webhook-Signature` peut toujours apparaître sur les livraisons de tests du portail des développeurs en tant qu''alias obsolète réservé au corps — vérifiez `X-Endorsed-Signature`. Pré-requis : votre secret webhook dans une var env, une route Express qui garde le corps brut. Résultat attendu : les charges utiles non reconnues ou falsifiées sont rejetées avec 401 avant l''exécution de tout gestionnaire.
import crypto from 'node:crypto';
import express from 'express';
const WEBHOOK_SECRET = process.env.ENDORSED_WEBHOOK_SECRET!;
const TOLERANCE_SECONDS = 5 * 60;
export function verifyWebhookSignature(
rawBody: string,
header: string | undefined,
nowSeconds = Math.floor(Date.now() / 1000),
): boolean {
if (!header) return false;
let timestamp: number | null = null;
let v1 = '';
for (const part of header.split(',')) {
const eq = part.indexOf('=');
if (eq === -1) continue;
const key = part.slice(0, eq).trim();
const value = part.slice(eq + 1).trim();
if (key === 't' && /^\d+$/.test(value)) timestamp = Number.parseInt(value, 10);
if (key === 'v1' && /^[a-f0-9]{64}$/i.test(value)) v1 = value.toLowerCase();
}
if (timestamp === null || !v1) return false;
if (Math.abs(nowSeconds - timestamp) > TOLERANCE_SECONDS) return false;
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody)
.digest('hex');
const a = Buffer.from(expected, 'hex');
const b = Buffer.from(v1, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
app.post(
'/webhooks/endorsed',
express.json({ verify: (req, _res, buf) => { (req as any).rawBody = buf.toString('utf8'); } }),
(req, res) => {
const sig = req.header('X-Endorsed-Signature');
if (!verifyWebhookSignature((req as any).rawBody, sig)) {
return res.status(401).send('Invalid signature');
}
res.sendStatus(200);
},
);Retournez 2xx dans les 30 secondes ou la livraison est marquée comme ayant échoué. Les tentatives infructueuses réessayent avec le ladder ci-dessus et restent rejouables depuis la console développeur.
Comment configurer un point de terminaison webhook
- 1
Créez le point de terminaison dans votre application
Ajoutez une route qui accepte les requêtes POST et renvoie HTTP 200 dans les 10 secondes. Toute réponse 2xx compte comme une livraison réussie.
- 2
Enregistrez le point de terminaison dans les paramètres de votre locataire
Allez dans Admin → Paramètres → Webhooks. Entrez l''URL de votre point de terminaison et sélectionnez les types d''événements souhaités. Un secret de signature est généré par point de terminaison.
- 3
Vérifiez la signature sur chaque demande
Lisez `X-Endorsed-Signature`. Recalculez HMAC-SHA256 sur `{timestamp}.{rawBody}` et comparaison en temps constant avec `v1` (voir l''exemple de code ci-dessus). Rejetez un en-tête manquant, une valeur hexadécimale incorrecte, un horodatage en dehors de ± 5 minutes ou une incompatibilité HMAC. `X-Webhook-Signature` est un alias obsolète sur certaines livraisons de test — ne le traitez pas comme le contrat en direct.
- 4
Retournez 2xx rapidement, traitez de manière asynchrone
Acquittez la livraison avec 200 dans les 10 secondes et mettez le corps de l''événement en file d''attente pour le traitement asynchrone. La console développeur affiche chaque tentative (en-têtes, corps, statut, timing) et vous permet de rejouer n''importe quelle livraison — pas besoin de relancer le flux de signature source juste pour tester votre gestionnaire.
Questions courantes
Une vraie charge utile webhook — document terminé
Lorsque toutes les parties ont signé, EndorsedSign POST cette charge utile sur votre point de terminaison enregistré. Vérifiez la signature HMAC, mettez-la en file d''attente et accusez réception avec 200.

Câblez votre premier webhook
Réclamez un bac à sable, enregistrez le point de terminaison dans Admin → Développeur → Webhooks, et inspectez ou rejouez chaque livraison depuis la console du développeur.