Projets et étapes
Référence du webhook : événements, en-têtes, signature et nouvelles tentatives
Le contrat de chaque envoi : événements du catalogue, en-têtes x-aproova-*, vérification de la signature et nouvelles tentatives.
Révisé le 14 novembre 2026
Avant de commencer
- Un webhook créé dans Paramètres > Intégrations (propriétaire de l’espace, Flux ou supérieure) et le secret de signature affiché dans le formulaire.
Aperçu rapide de la tâche
Commencez par ces étapes. Si la tâche en comporte d’autres, elles apparaissent juste en dessous.
- Étape 1
Événements du catalogue : review.created (révision créée), review.version_uploaded (version envoyée), review.comment_created (commentaire créé), review.verdict_submitted (décision envoyée par un participant), review.approved (révision validée), review.rejected (révision refusée), review.changes_requested (modifications demandées), review.approval_reopened (validation rouverte), review.unlocked (révision déverrouillée). Validation rouverte et révision déverrouillée ne sont envoyés qu’aux webhooks qui les cochent ; les abonnements existants continuent de recevoir uniquement leurs événements actuels. Le bouton Tester envoie l’événement webhook.test.
- Étape 2
En-têtes de chaque envoi : x-aproova-event (type d’événement), x-aproova-delivery (identifiant de l’envoi), x-aproova-timestamp (secondes depuis 1970, UTC) et x-aproova-signature. Sont aussi envoyés user-agent Aproova-Webhooks/1.0 et, s’il y a un corps, content-type application/json. Les en-têtes personnalisés ne remplacent pas ces noms.
- Étape 3
Signature : x-aproova-signature = « sha256= » suivi du HMAC-SHA256 en hexadécimal, calculé avec le secret du webhook sur le texte « ${timestamp}.${body} », où timestamp est la valeur de x-aproova-timestamp et body le corps brut reçu (texte vide pour GET, DELETE ou sans corps). Calculez-le sur les octets reçus, avant de décoder le JSON, et comparez en temps constant.
Pas à pas
- 4Corps par défaut (JSON) : event, event_id, created_at, workspace_id, locale et, lorsqu’ils existent, proof, version, folder, teams, comment, decision, actor et whatsapp. Les champs vides sont omis. Le texte des commentaires internes n’est jamais envoyé.
- 5Champs de décision facultatifs : verification_method (authenticated_user, email_otp ou declared) et actor_verified (true uniquement pour authenticated_user et email_otp). Ils n’apparaissent que dans les événements de décision qui portent cette preuve ; dans un corps personnalisé, utilisez {{data.verification_method}} et {{data.actor_verified}}.
- 6Réponse : tout statut 2xx compte comme livré. Aproova attend jusqu’à 6 secondes.
- 7Nouvelles tentatives : erreurs réseau, délais dépassés et statuts 408, 425, 429 et 5xx sont retentés ; les autres 4xx non. Il y a au plus 4 tentatives : la 2e environ 5 minutes après le 1er échec, la 3e environ 30 minutes après et la 4e environ 120 minutes après. Après la 4e, l’envoi est marqué en échec définitif dans l’historique.
- 8Chaque nouvelle tentative reprend le même event_id et le même x-aproova-delivery. Utilisez-le pour ignorer les répétitions à destination. Si l’espace n’a plus d’offre avec webhooks, l’envoi échoue sans nouvelle tentative.
Ce qui doit se passer
Votre service vérifie la signature, reconnaît les répétitions par event_id et répond 2xx rapidement.
Problèmes courants
- Signature incorrecte : calculez-la sur le corps brut, sans reformater le JSON, avec le secret actuel (générer un nouveau secret invalide l’ancien).
- Action en double à destination : une réponse lente ou un 5xx déclenche une nouvelle tentative. Conservez l’event_id déjà traité.
- Un nouvel événement n’arrive pas : cochez validation rouverte ou révision déverrouillée dans la liste des événements du webhook.