GLPI 11 dispose de webhooks natifs : à chaque ticket créé, modifié ou supprimé, il prévient un autre système par HTTP, avec signature et nouvelles tentatives. Nous l'avons testé sur notre GLPI de support et la première configuration n'a rien livré. La raison n'apparaissait sur aucun écran : GLPI refuse toute URL avec un port, comme :8080 ou le :5678 par défaut de n8n. Ce guide montre comment le configurer, ce que le test a mesuré et les trois détails qui bloquent l'intégration.
Besoin d'aller au-delà du webhook sortant, avec des conditions, plusieurs étapes ou la réception de données externes ? Consultez Automatisations et webhooks dans GLPI avec NexTool.
Ce que fait le webhook natif (et ce qu'il ne fait pas)
Le webhook de GLPI 11 est sortant : lorsqu'un événement survient sur un élément, GLPI construit un message et l'envoie à une URL. Il sert à prévenir un ERP, ouvrir une carte dans Teams, alimenter un tableau de bord ou déclencher un flux dans n8n.
- Événements : nouveau, mise à jour et suppression.
- Éléments : les mêmes que la nouvelle API de GLPI 11, comme les tickets, problèmes, changements, actifs et utilisateurs.
- Message : par défaut, l'élément au format de l'API (statut, demandeur, équipe, entité, dates), modifiable avec des variables.
Il ne reçoit rien. Pour qu'un autre système crée ou modifie des tickets dans GLPI, il faut passer par l'API.
Où le configurer
Dans Configuration > Webhooks > Ajouter :
| Champ | À quoi il sert |
|---|---|
| Entité et récursif | Ne se déclenche que pour les éléments de cette entité (et de ses entités filles, si récursif) |
| Type d'élément et événement | Ex. : Ticket + Nouveau |
| URL | Destination. Accepte des variables, comme l'ID de l'élément dans le chemin |
| Méthode HTTP | POST, PUT, PATCH ou GET |
| Nombre de tentatives | Combien de fois renvoyer si la destination échoue |
| Journaliser dans l'historique de l'élément | Enregistre chaque envoi dans l'historique du ticket |
| Enregistrer le corps de la réponse | Conserve ce que la destination a répondu (doit être autorisé dans la configuration du serveur) |
Et dans les onglets :
- Critères : filtre les éléments qui déclenchent l'envoi, avec les mêmes critères que la recherche. Ex. : uniquement les tickets de la catégorie « Achats ».
- Éditeur de charge utile : remplace le message par défaut par votre propre modèle, avec aperçu.
- Sécurité : secret de la signature, défi de validation de l'URL et authentification OAuth.
- En-têtes personnalisés : comme
AuthorizationouContent-Type.
Le test : ce que nous avons mesuré
Nous avons créé deux webhooks dans l'entité de test de notre GLPI de support (entreprise fictive Acme) et ouvert des tickets. L'un pointait vers une destination qui répond 200 ; l'autre, vers une destination qui répond une erreur 500.

| Ce que nous avons vérifié | Résultat |
|---|---|
URL avec port (http://destino:8080/...) |
Refusée comme « unsafe », rien n'est envoyé |
| La même URL sans port | Acceptée |
| Délai entre l'ouverture du ticket et la livraison | 8 secondes (passage suivant du cron) |
| Destination en erreur 500 et « Nombre de tentatives » = 2 | 3 envois, un par minute, puis GLPI abandonne |
Signature X-GLPI-signature |
Conforme : HMAC-SHA256 du corps + X-GLPI-timestamp |
En-tête Content-Type |
Absent |
| Corps | {"event": "new", "item": {...}} de 2,1 Ko pour un ticket simple |
Les trois détails qui bloquent l'intégration
1. Une URL avec port est refusée
GLPI 11 n'appelle que les URL qui passent une liste d'autorisation (protection contre l'utilisation abusive du serveur). La règle par défaut accepte le domaine, l'IP et le chemin, mais n'accepte pas de port. L'erreur n'apparaît pas à l'écran : elle reste dans webhook.log, sous la forme « Webhook target URL ... is unsafe ».
Nous avons testé la fonction de GLPI lui-même :
| URL | Résultat |
|---|---|
https://n8n.empresa.com.br/webhook/abc |
acceptée |
https://n8n.empresa.com.br:5678/webhook/abc |
refusée |
http://localhost:5678/webhook/abc |
refusée |
http://localhost/webhook/abc |
acceptée |
Solution : publiez la destination sur le port par défaut (443 ou 80), généralement derrière un proxy inverse. Cela règle aussi la question du HTTPS. Il est possible d'élargir la liste avec la constante GLPI_SERVERSIDE_URL_ALLOWLIST, mais elle s'applique à tout accès du serveur à des URL externes : modifiez-la avec prudence.
2. Sans Content-Type, la destination peut ne pas comprendre le JSON
GLPI envoie le corps en JSON, mais sans l'en-tête Content-Type. Des outils comme n8n et de nombreux frameworks ne lisent le corps comme du JSON que si l'en-tête l'indique.
Solution : dans En-têtes personnalisés, ajoutez Content-Type: application/json.
3. Sans cron, rien ne part
Le webhook n'est pas envoyé immédiatement : il est placé dans une file d'attente, et l'action automatique queuedwebhook l'envoie chaque minute, jusqu'à 50 à la fois. Si le cron de GLPI ne tourne pas, la file ne fait que grossir.
Solution : cron en ligne de commande chaque minute (voir l'étape 6 de comment installer GLPI 11) et, de temps en temps, un coup d'œil à Configuration > Webhooks > File d'attente des webhooks.
Comment valider la signature côté destination
Chaque envoi contient deux en-têtes : X-GLPI-timestamp (moment de l'événement) et X-GLPI-signature. La signature est le HMAC-SHA256 du corps suivi du timestamp, avec le secret du webhook. En Python :
import hmac, hashlib
def assinatura_valida(corpo: bytes, timestamp: str, assinatura: str, segredo: str) -> bool:
calc = hmac.new(segredo.encode(), corpo + timestamp.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(calc, assinatura)
Deux précautions : - Le timestamp est celui de l'événement, pas de l'envoi. Il se répète lors des nouvelles tentatives. Si vous refusez les messages « anciens », prévoyez une fenêtre qui couvre les tentatives (quelques minutes). - Utilisez le corps brut, tel qu'il est arrivé. Si votre code décode puis réencode le JSON, la signature ne correspondra pas.
Pour ceux qui ont besoin de plus de garanties, l'onglet Sécurité propose le défi de validation : avant d'envoyer, GLPI appelle l'URL avec un crc_token, et la destination doit répondre avec le HMAC de ce jeton. Il existe aussi OAuth (client credentials) : GLPI obtient un jeton auprès du serveur d'autorisation et l'envoie en tant que Bearer.
Quand le webhook natif ne suffit pas
- Recevoir des données d'un autre système : il faut l'API.
- Une logique avec plusieurs conditions et étapes, comme « si la catégorie est X et que le demandeur fait partie de la direction, prévenir un canal et ouvrir une tâche » : les Critères filtrent, mais n'enchaînent pas d'actions.
- Voir sur un seul écran ce qui a échoué et renvoyer en un clic. La file affiche le statut, mais le diagnostic se trouve dans
webhook.log.
Dans ces cas, on fait appel à un orchestrateur comme n8n ou au module Automatisations de NexTool.
Checklist avant la mise en production
- Destination en HTTPS, sur le port par défaut, sans
:portadans l'URL. - En-tête
Content-Type: application/json. - Signature validée côté destination, avec le corps brut et une fenêtre de temps pour les tentatives.
- Critères pour ne pas tout déclencher.
- « Nombre de tentatives » selon l'importance (3 est un bon début).
- Cron de GLPI exécuté chaque minute.
- « Journaliser dans l'historique de l'élément » activé, pour que le technicien voie ce qui a été envoyé.
- Test avec un ticket fictif avant d'ouvrir à tous.
Test NexTool du 3 octobre 2026, sur le GLPI 11.0.7 de notre support, entité de test avec des données fictives. Les webhooks et tickets de test ont été supprimés ensuite. Comportements également vérifiés dans le code source de GLPI 11.