Webhooks : recevoir les événements de votre compte en temps réel

Créer un endpoint, vérifier la signature HMAC, gérer les réessais et l'idempotence : le guide complet pour intégrer nos événements à vos systèmes.

J
Jessy DAVID

Les webhooks permettent à vos propres systèmes d'être prévenus dès qu'il se passe quelque chose sur votre compte : un serveur prêt, une facture émise, un service suspendu. Plutôt que d'interroger notre API en boucle, vous recevez une requête HTTP au moment où l'événement survient.

Cet article couvre la création d'un endpoint depuis votre espace client et les points d'implémentation qui font la différence entre une intégration qui tient et une qui perd des événements.

Créer un endpoint

Dans Webhooks, le bouton Créer un endpoint ouvre le formulaire.

L'URL de destination doit être en HTTPS. Les adresses réseau internes sont refusées : pas de localhost, pas d'IP privée, pas d'adresse de métadonnées cloud. Pour développer en local, exposez votre machine via un tunnel HTTPS public.

La description est facultative mais devient vite précieuse quand vous avez plusieurs intégrations. « Intégration facturation » vous parlera davantage qu'une URL brute dans six mois.

Les événements se sélectionnent un par un, par catégorie entière, ou tous d'un coup. Ne vous abonnez qu'à ce que vous traitez réellement : chaque événement inutile est une requête que votre serveur doit encaisser pour rien.

Les options avancées permettent d'ajouter des en-têtes personnalisés, au format Nom: valeur, un par ligne, et de régler la rétention de l'historique entre 1 et 90 jours.

Le secret : à copier immédiatement

À la création, un secret de signature s'affiche. Il ne sera plus jamais montré. Copiez-le et rangez-le dans votre gestionnaire de secrets avant de fermer la fenêtre.

Si vous le perdez, la solution existe : la rotation, décrite plus bas. Mais elle demande un déploiement, autant l'éviter.

Format des livraisons

Chaque livraison est une requête POST dont le corps est un objet JSON contenant l'identifiant de l'événement, son nom, sa charge utile et son horodatage. Les en-têtes portent les métadonnées :

  • X-Webhook-Event — le nom de l'événement, par exemple server.ready.
  • X-Webhook-Id — l'identifiant de l'événement, stable entre toutes les tentatives et tous les rejeux.
  • X-Webhook-Delivery-Id — l'identifiant de cette tentative précise.
  • X-Webhook-Attempt — le numéro de tentative, à partir de 1.
  • X-Webhook-Signature — la signature HMAC-SHA256, au format t=<timestamp>,v1=<hex>.

Vérifier la signature

C'est le point le plus important de toute l'intégration. Sans vérification, n'importe qui connaissant votre URL peut vous envoyer de faux événements.

La signature v2 couvre la chaîne composée de l'horodatage et du corps de la requête. Comme l'horodatage est signé, une requête interceptée devient inutilisable au-delà de quelques minutes.

Deux règles à ne pas contourner :

  • Vérifiez la signature sur le corps brut de la requête, avant tout parsing JSON. Parser puis resérialiser modifie les octets et invalide la signature. En Next.js, cela signifie lire le corps avec await req.text(), jamais await req.json().
  • Comparez les signatures en temps constant, avec crypto.timingSafeEqual et non l'opérateur ===.

Un point de conception à connaître : testez toutes les valeurs de signature présentes dans l'en-tête, pas seulement la première. C'est ce qui rendra votre intégration transparente aux rotations de secret.

La rotation du secret

Depuis l'onglet Sécurité de l'endpoint, Renouveler le secret génère un nouveau secret et ouvre une fenêtre de grâce de 24 heures. Pendant cette période, chaque livraison porte deux signatures : l'ancienne et la nouvelle. Vous déployez le nouveau secret quand cela vous arrange, sans interruption ni perte d'événement.

Un consommateur qui teste toutes les signatures présentes traverse la rotation sans aucune modification de code.

Idempotence : la règle à ne pas négliger

Un même événement peut vous être livré plusieurs fois : nouvelle tentative après un échec, rejeu manuel depuis votre espace client, ou simple temporisation réseau alors que votre serveur avait déjà traité la requête.

Toutes ces livraisons partagent le même X-Webhook-Id. Stockez les identifiants déjà traités et ignorez les doublons. C'est la seule façon de garantir un traitement exactement une fois. Sans cela, une simple lenteur réseau peut vous faire facturer deux fois un client ou envoyer deux emails.

Réessais et désactivation automatique

Une réponse hors 2xx déclenche une nouvelle tentative, selon un backoff exponentiel étalé sur environ six heures : immédiat, 10 secondes, 30 secondes, 2 minutes, 10 minutes, 30 minutes, 1 heure, puis 3 heures. Un en-tête Retry-After est respecté s'il est présent.

Un code 4xx autre que 408 et 429 est interprété comme un refus définitif et interrompt les tentatives : ne répondez 400 que si vous voulez vraiment que l'événement soit abandonné.

Après 20 échecs consécutifs, l'endpoint est désactivé automatiquement et un email vous est envoyé. Les événements concernés restent consultables et rejouables depuis l'onglet Livraisons : corrigez votre serveur, réactivez l'endpoint, puis rejouez ce qui a été manqué.

Contraintes techniques

  • Protocole — HTTPS obligatoire, sur le port 80 ou 443.
  • Redirections — non suivies. Répondez directement sur l'URL déclarée.
  • Délai d'attente — 15 secondes par tentative.
  • Quotas — 10 endpoints par compte, 10 en-têtes personnalisés par endpoint.

Ces 15 secondes ont une conséquence directe sur votre code : répondez 200 dès que vous avez validé la signature et enregistré l'événement, puis faites le travail lourd de façon asynchrone. Un traitement métier long exécuté avant la réponse finira par dépasser le délai et provoquer des réessais parfaitement inutiles.

Tester et diagnostiquer

L'onglet Vue d'ensemble de chaque endpoint affiche son taux de succès, le nombre de livraisons réussies et échouées, les échecs consécutifs et les dates du dernier succès et du dernier échec. Le bouton Tester envoie un événement d'exemple, avec le code HTTP et le temps de réponse obtenus.

L'onglet Livraisons liste l'historique, filtrable sur les réussites et les échecs. Chaque entrée s'inspecte : vous y voyez la charge utile reçue, la réponse de votre serveur, l'erreur éventuelle et la date de la prochaine tentative. Le bouton Rejouer replace la livraison dans la file.

Une documentation technique complète, avec un exemple de gestionnaire Next.js et la référence de tous les événements, est accessible depuis le bouton Documentation de la page Webhooks.


Retour au blog