Webhooks sortants

Vaks PM · Guide d'intégration · Webhooks · Juillet 2026

Ce que vous obtiendrez. Vaks PM appelant un point de terminaison HTTP de votre choix dès qu'il se passe quelque chose — une tâche créée, un commentaire posté, un projet activé — chaque requête étant signée pour que votre récepteur puisse prouver qu'elle vient bien de Vaks PM. Les livraisons sont réessayées, journalisées et rejouables. Un format de carte Microsoft Teams intégré vous permet de publier dans un canal sans écrire la moindre ligne de code.

Ce que ça fait — et ce que ça ne fait pas

Événements souscriptibles

Vingt-sept événements, plus le joker * qui souscrit à l'ensemble — y compris à ceux ajoutés dans de futures versions.

FamilleÉvénements
Tâchestask.created · task.updated · task.deleted · task.moved · task.assigned · task.unassigned · task.completed
Flux de travail des agentstask.claimed · task.released · task.review_requested · task.changes_requested · task.approved · deliverable.submitted · deliverable.reviewed
Projetsproject.created · project.updated · project.activated · project.announcement
Collaborationcomment.created
Compétencesskill_request.created · skill_request.acknowledged · skill_request.resolved · skill_request.rejected · skill_request.reminded
Exploitationaudit.alert · backup.failed · automation.alert
Les trois événements d'exploitation n'atteignent que les webhooks de périmètre organisation. audit.alert (échecs de connexion répétés), backup.failed et automation.alert ne sont rattachés à aucun projet : un webhook de périmètre projet ou équipe ne les reçoit donc jamais. project.activated mérite aussi d'être connu : il se déclenche au passage à l'état actif et constitue le signal qu'un provisionneur externe doit attendre.

Prérequis

CôtéCe qu'il vous faut
Votre côtéUn point de terminaison HTTPS qui répond 2xx rapidement. Tout le reste compte comme un échec. Il doit être résoluble publiquement — les adresses privées, de loopback et link-local sont refusées, voir gouvernance. Pour un canal Teams, un flux Power Automate suffit ; aucun code.
Vaks PMorg:manage pour les webhooks à l'échelle de l'organisation. Les chefs de projet peuvent créer des webhooks pour leur propre projet sans être administrateurs — voir périmètre & délégation.

Étape 1 — Créer le point de terminaison

Ouvrez Admin → Intégrations → Webhooks → Endpoints et pressez Nouveau webhook.

ChampQuoi renseigner
LibelléTexte libre pour votre propre usage, affiché dans la liste et dans le journal des livraisons.
URLVotre récepteur. HTTPS fortement recommandé — http:// est accepté mais envoie la charge utile en clair. Seuls les ports 80, 443, 8080 et 8443 sont autorisés.
ÉvénementsCochez ce que vous voulez. Préférez nommer les événements que vous traitez plutôt que de souscrire à tout : le joker livrera de futurs types d'événements que votre récepteur n'a jamais vus.
PérimètreToute l'org, Un projet ou Une équipe. Voir ci-dessous.
Format du payloadJSON (brut) pour vos propres intégrations, Teams (Adaptive Card) pour publier dans un canal. Voir le format Teams.
SecretLaissez vide et un secret est généré pour vous. C'est la clé que votre récepteur utilise pour vérifier les signatures.
ActifCochez pour commencer à livrer.
Le secret reste lisible par les administrateurs. Contrairement aux jetons API, il n'est pas masqué après création — la liste comporte un bouton Afficher, donc quiconque a accès à cet écran peut le récupérer à tout moment. Traitez-le comme un secret partagé entre deux systèmes, pas comme un identifiant appartenant à une personne. Régénérer le remplace instantanément, sans fenêtre de recouvrement : l'ancien secret cesse de signer dès la livraison suivante, mettez donc à jour votre récepteur dans la même fenêtre de maintenance.

Étape 2 — Vérifier la signature

Chaque requête porte une signature HMAC-SHA256 du corps, calculée avec le secret de votre webhook. C'est sa vérification qui rend le point de terminaison sûr à exposer : sans elle, quiconque devine votre URL peut poster de faux événements.

Deux détails décident si votre implémentation est correcte :

// Node.js / Express — attention : express.raw, pas express.json
const crypto = require('crypto');

app.post('/vaks-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const expected =
    'sha256=' + crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
  const got = req.get('X-Vaks-Signature') || '';

  const a = Buffer.from(expected), b = Buffer.from(got);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return res.status(401).end();
  }

  const event = JSON.parse(req.body.toString('utf8'));
  // Dédupliquez : un même deliveryId peut arriver plusieurs fois.
  if (alreadyHandled(req.get('X-Vaks-Delivery'))) return res.status(200).end();

  handle(event);
  res.status(200).end();   // répondez 2xx vite ; faites le travail de façon asynchrone
});
La signature ne couvre pas l'horodatage : elle prouve donc l'authenticité mais pas la fraîcheur — une requête capturée pourrait en principe être rejouée contre vous. Deux conséquences : dédupliquez sur X-Vaks-Delivery, qui reste stable à travers les réessais d'une même livraison, et considérez X-Vaks-Timestamp comme purement informatif. Si le rejeu compte dans votre modèle de menace, rejetez les livraisons dont l'horodatage est éloigné de l'instant présent, en plus de vérifier la signature.

Étape 3 — Tester

Pressez Envoyer un test sur la ligne du webhook. Cela envoie immédiatement un événement ping, quels que soient les événements auxquels vous avez souscrit : il fonctionne donc toujours comme contrôle de connectivité.

Ouvrez ensuite Livraisons récentes sous la liste et vérifiez que la ligne indique SUCCESS avec une réponse 2xx. Si ce n'est pas le cas, dépliez Détails — l'erreur, la charge utile exacte envoyée et le corps de réponse de votre récepteur y sont tous enregistrés. Ce panneau est l'outil de débogage le plus utile de cette page.

L'enveloppe du ping porte le nom de l'événement deux fois, une fois au niveau de l'enveloppe et une fois dans payload. C'est attendu, et vrai uniquement pour l'événement de test.

Charge utile & en-têtes

Au format brut, chaque requête a la même enveloppe, les données propres à l'événement étant imbriquées sous payload :

{
  "event": "task.created",
  "deliveryId": "9f1c…",
  "organizationId": "…",
  "at": "2026-07-19T21:04:11.482Z",
  "payload": { }
}
En-têteSignification
X-Vaks-EventLe nom de l'événement, pour router sans analyser le corps.
X-Vaks-DeliveryIdentifiant de livraison. Stable à travers chaque réessai d'une même livraison — c'est votre clé de déduplication.
X-Vaks-Signaturesha256= suivi du HMAC du corps brut, en hexadécimal minuscule.
X-Vaks-TimestampHeure d'envoi, en secondes epoch. Régénérée à chaque réessai, et non couverte par la signature.
User-AgentVaks-PM-Webhook/1.0

La forme des charges utiles varie selon l'événement et se découvre au mieux depuis une livraison réelle : souscrivez, déclenchez l'action, et lisez la charge utile enregistrée dans le journal des livraisons. Construisez votre récepteur de façon défensive — traitez les champs comme facultatifs et ignorez ce que vous ne reconnaissez pas, car les charges utiles gagnent des champs d'une version à l'autre.

Réessais & échecs

Un webhook qui échoue en continu est désactivé automatiquement. Après 5 livraisons consécutives ayant épuisé toutes leurs tentatives — 25 requêtes en échec au total — le webhook est désactivé et signalé ⚠︎ désactivé auto dans la liste. Tout succès remet le compteur à zéro. Pour le rétablir, modifiez le webhook et cochez Actif ; cela remet aussi le compteur à zéro. Rien n'est livré entre-temps et il n'y a pas de rattrapage : les événements survenus pendant la désactivation sont perdus, pas mis en file.

Format Microsoft Teams

Choisir Teams (Adaptive Card) remplace l'enveloppe JSON par un message Teams enveloppant une Adaptive Card. Le corps envoyé par Vaks PM ressemble à ceci :

{
  "type": "message",
  "attachments": [{
    "contentType": "application/vnd.microsoft.card.adaptive",
    "content": { /* une Adaptive Card : titre, accroche, jusqu'à 8 faits */ }
  }]
}

Cette forme est exactement ce qu'attend Teams. La carte affiche un titre pour l'événement, une accroche d'une ligne tirée de la charge utile, et jusqu'à huit faits lorsqu'ils sont présents : statut, priorité, assigné, auteur, échéance, équipe, compétence et projet. Il y a deux façons de la faire arriver dans un canal — choisissez-en une.

Option A — Teams Workflows / Power Automate (recommandé)

C'est le chemin actuel de Microsoft, et celui qui continuera de fonctionner. Microsoft retire les anciens connecteurs de webhook entrant (option B) : préférez donc celui-ci pour toute nouvelle configuration.

  1. Dans le canal Teams cible, ouvrez le menu Workflows (ou passez directement par Power Automate). Choisissez le modèle « Post to a channel when a webhook request is received ».
  2. Sélectionnez l'équipe et le canal où publier, puis créez le flux. Son déclencheur — « When a Teams webhook request is received » — génère une URL de rappel. Copiez-la.
  3. Dans Vaks PM, créez un webhook (ou modifiez-en un) : réglez le Format du payload sur Teams (Adaptive Card), collez l'URL de rappel dans URL, et cochez les événements voulus.
  4. De retour dans le flux, assurez-vous que l'action de publication reçoit bien l'Adaptive Card issue du corps de la requête. Vaks PM envoie la carte sous attachments[0].content ; si le modèle ne la référence pas déjà, pointez l'action « Post card in a chat or channel » vers ce chemin.
  5. Enregistrez le flux, puis pressez Envoyer un test sur le webhook dans Vaks PM. Une carte doit apparaître dans le canal en quelques secondes. Sinon, ouvrez Livraisons récentes — un 2xx sans carte signifie généralement que le flux s'est exécuté mais que le champ de la carte n'était pas relié à attachments[0].content.

Option B — Webhook entrant Teams (le plus simple, en cours de retrait)

Si votre tenant autorise encore les connecteurs de webhook entrant, aucune configuration de flux n'est nécessaire — le corps envoyé par Vaks PM est exactement ce qu'attend le connecteur.

  1. Dans le canal, menu ConnectorsIncoming WebhookConfigure. Nommez-le, réglez éventuellement une icône, puis Create.
  2. Copiez l'URL générée — elle est sur ….webhook.office.com.
  3. Dans Vaks PM, créez le webhook avec le Format du payload = Teams (Adaptive Card) et cette URL. Envoyer un test ; la carte se publie directement.
Microsoft déprécie les connecteurs de webhook entrant. De nombreux tenants les ont déjà désactivés. Si Incoming Webhook est absent de la liste des connecteurs, ou si l'URL cesse de fonctionner, c'est la raison — passez à l'option A.
La liste d'autorisation de tenants peut bloquer l'URL. Si vous avez activé Tenants Entra ID autorisés (Teams) sous Gouvernance, Vaks PM vérifie le tenant présent dans les URL Microsoft et refuse celui appartenant à un autre tenant — cela couvre webhook.office.com (option B) et les URL Power Automate. Un déclencheur Workflows hébergé ailleurs (par exemple sur logic.azure.com) n'est pas couvert par ce contrôle, mais est soumis à la liste Domaines autorisés (allowlist) si vous en définissez une — ajoutez-y l'hôte du déclencheur. Un envoi bloqué apparaît dans le journal des livraisons avec la mention Bloqué par la gouvernance et le motif.
Deux choses à anticiper une fois que ça fonctionne. L'enveloppe Vaks est absente dans ce format — il n'y a ni deliveryId ni organizationId dans le corps, seulement dans les en-têtes : un flux qui en a besoin doit donc lire les en-têtes. Et la carte ne porte aucun lien de retour vers l'élément : le worker qui la rend ne peut pas résoudre votre adresse publique, un bouton pointerait donc dans le vide. Les titres de cartes et les libellés de champs sont toujours en français, quelle que soit la langue de votre interface.

Périmètre & délégation

Le périmètre d'un webhook décide quels événements l'atteignent :

PérimètreReçoitQui peut le créer
Toute l'orgTout, y compris les événements d'exploitation.Les administrateurs uniquement, toujours.
Un projetUniquement les événements portant ce projet.Les administrateurs, et les rôles délégués — voir ci-dessous.
Une équipeLes événements rattachés à cette équipe, plus les événements des projets auxquels l'équipe est affectée.Les administrateurs, et les leads d'équipe selon la même politique.

La délégation est pilotée par Qui peut créer un webhook, sous Admin → Intégrations → Webhooks → Gouvernance :

Lorsque c'est permis, les chefs de projet y accèdent depuis l'onglet Gérer → Intégrations du projet, qui n'apparaît que si leur rôle l'autorise. Le périmètre est forcé côté serveur à leur propre projet : un utilisateur délégué ne peut donc pas l'élargir — ni à la création, ni en le modifiant ensuite.

Listes d'autorisation & protection anti-SSRF

Parce qu'un webhook envoie vos données à une adresse saisie par quelqu'un, les destinations sont contrôlées. Deux réglages sous Gouvernance resserrent cela, et il vaut la peine de les activer tous les deux avant de déléguer la création de webhooks aux chefs de projet :

RéglageEffet
Domaines autorisés (allowlist)Lorsqu'elle est non vide, seuls ces hôtes et leurs sous-domaines peuvent être ciblés. Vide signifie tout hôte public.
Tenants Entra ID autorisés (Teams)Ne s'applique qu'aux points de terminaison Microsoft — webhooks entrants Teams et Power Automate. Vaks PM extrait l'identifiant de tenant depuis l'URL et refuse les destinations appartenant à un autre tenant, de sorte que les données ne peuvent pas être publiées dans le Microsoft 365 de quelqu'un d'autre.

Indépendamment de tout réglage, les cibles internes sont toujours refusées : localhost, .local, .internal, ainsi que les plages d'adresses privées, de loopback ou link-local. Ce contrôle a lieu deux fois — à l'enregistrement de l'URL puis de nouveau à l'envoi, avec une résolution DNS réelle, ce qui déjoue également un nom d'hôte qui ne résoudrait vers une adresse privée que plus tard.

La gouvernance s'applique rétroactivement. Les règles sont réévaluées à chaque envoi, pas seulement à l'enregistrement : resserrer la liste d'autorisation arrête donc immédiatement les webhooks existants qui n'y sont plus conformes. Leurs livraisons sont enregistrées comme des échecs, avec le motif, plutôt que de disparaître silencieusement. Attendez-vous à cela lorsque vous introduisez une liste d'autorisation sur une instance en production.
Les environnements Power Platform personnalisés ne peuvent pas être vérifiés tant que la liste d'autorisation de tenants Entra est active : ils sont donc refusés. Si vous en utilisez un, vous devrez laisser cette liste vide et vous appuyer sur la liste d'autorisation de domaines à la place.

Journal des livraisons

Livraisons récentes, sous la liste des points de terminaison, enregistre chaque tentative : statut et code de réponse, événement, webhook ciblé, date de mise en file, et nombre de tentatives nécessaires. Déplier une ligne montre l'erreur, la charge utile envoyée et le corps de réponse de votre récepteur (les 1000 premiers caractères).

Une livraison en échec peut être rejouée avec Réessayer. Elle réutilise la charge utile stockée et le même identifiant de livraison : un récepteur qui déduplique correctement la reconnaîtra donc — mais l'horodatage et la signature sont recalculés. La destination est d'abord re-contrôlée au regard de la gouvernance actuelle, si bien qu'un réessai vers une adresse désormais interdite est refusé.

Le journal des livraisons n'est jamais purgé. Il n'y a ni réglage de rétention ni tâche de nettoyage : les lignes s'accumulent donc pendant toute la durée de vie de l'instance. Sur une organisation active avec un webhook bavard, cela croît régulièrement. À surveiller au même titre que le reste de la croissance de votre base de données, et à signaler à votre éditeur si cela devient significatif.

Dépannage

SymptômeCause & correctif
La signature ne correspond jamaisPresque toujours le problème du corps brut : le corps a été analysé puis re-sérialisé avant la vérification. Capturez les octets tels que reçus. Vérifiez aussi que vous avez conservé le préfixe sha256= dans la comparaison.
Le test réussit, mais les vrais événements n'arrivent jamaisLe test ignore votre souscription aux événements. Vérifiez que les événements sont bien cochés, et que le périmètre correspond — un webhook de périmètre projet ne reçoit rien pour les autres projets, et ne reçoit jamais les événements d'exploitation.
Bloqué par la gouvernance dans le journal des livraisonsLa destination enfreint une règle : absente de la liste d'autorisation de domaines, adresse privée, port non autorisé, ou URL Microsoft dont le tenant n'est pas permis. Le motif enregistré indique laquelle.
Tout a échoué d'un coup, et le webhook est maintenant désactivé5 livraisons consécutives épuisées. Corrigez le récepteur, puis modifiez le webhook et cochez Actif. Les événements manqués pendant la désactivation ne sont pas rejoués.
Événements en doubleC'est attendu. Réessais, et certaines actions émettant deux événements. Dédupliquez sur X-Vaks-Delivery et considérez comme normal l'appariement de task.updated avec un événement plus spécifique.
Les livraisons s'arrêtent après une régénérationLa régénération n'a pas de fenêtre de recouvrement. Le récepteur doit détenir le nouveau secret avant la livraison suivante.
Délais dépassés sous charge10 secondes par tentative, et le chronomètre inclut votre traitement. Accusez réception avec un 2xx d'abord, travaillez ensuite.

Ce qui est journalisé

La création, la modification, la suppression d'un webhook et la régénération de son secret sont toutes auditées en sévérité critique — un webhook est un chemin d'exfiltration de données, ses changements sont donc traités comme des événements de sécurité. Vous les retrouverez sous Admin → Sécurité & Conformité → Journal d'audit, avec l'acteur et la cible.


À lire aussi : toutes les intégrations · exploitation pour l'alerte de sauvegarde, qui utilise l'événement backup.failed.