Développeurs

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.

HMAC

Signature de demande SHA-256

Per-webhook secret, envoyé comme X-Endorsed-Signature

10s

Délai de livraison écoulé

Retournez 2xx dans la fenêtre ou la tentative échoue

5×

Réessaye après la première tentative

60s, 5m, 15m, 1h, puis 6h

Replay

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énementQuand il se déclencheChamps clés « données »
document.createdVous téléchargez un document via le APIID document, ID client, ID Document externe
document.sentLien de signature envoyé au premier destinatairedocumentId, customerId, canal
document.viewedSigner ouvre le lien de signaturedocumentId, signataireEmail, consulté à
document.signedLe signataire individuel termine son étapedocumentId, signataireEmail, signéAt
document.completedToutes les parties ont signédocumentId, terminé à, downloadUrl
document.declinedUn signataire refuse explicitementdocumentId, signataireEmail, raison
document.expiredLe document atteint sa date d''expiration sans être signédocumentId, expiré à
signing.startedLe 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 clientID client, ID client externe
modèle.créé / .mis à jourVous modifiez un modèletemplateId, 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.

typescript
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. 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. 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. 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. 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.

Historique des événements de livraison avec entrées du cycle de vie des documents
Historique des événements de livraison : événements du cycle de vie signés avec horodatages et résultats d''état pour la validation opérationnelle.

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.