Le webhook Kanal vous notifie en temps réel quand un de vos contacts envoie un message WhatsApp à votre numéro. Idéal pour brancher un bot, alimenter un CRM, ou déclencher des automatisations côté serveur.
Depuis l'interface Kanal, ajoutez l'URL HTTPS publique de votre serveur. Kanal enverra une requête POST à cette URL à chaque message entrant, avec un body JSON décrit ci-dessous.
Chaque webhook envoyé suit la même enveloppe standardisée :
{
"id": "evt_01HRXYZ...",
"type": "message.received",
"api_version": "2026-05-13",
"created_at": "2026-05-13T10:00:00+00:00",
"phone_number_id": 123,
"data": {
"contact": { ... },
"message": { ... }
}
}
Champs racine :
Champ | Description |
|---|---|
| Identifiant unique de l'event. Utilisez-le pour dédupliquer côté serveur. |
| Type d'event. Pour l'instant : |
| Version du contrat webhook. Permet de gérer les évolutions sans casse. |
| Date d'émission de l'event au format ISO 8601. |
| ID du numéro WhatsApp Kanal qui a reçu le message. |
| Objet contenant le contact et le message reçu. |
L'objet data contient toujours deux sous-objets : contact et message.
{
"id": 6789,
"phone_number": "33612345678",
"name": "Jean Dupont",
"country_code": "FR"
}
{
"id": 98765,
"wamid": "wamid.HBgL...",
"type": "text",
"content": "Bonjour, j'ai une question",
"media": null
}
Le champ content contient toujours le texte exploitable du message (corps texte, caption d'un média, label d'un bouton cliqué). Le champ media est rempli uniquement pour les médias.
{
"id": "evt_01HRXYZ...",
"type": "message.received",
"api_version": "2026-05-13",
"created_at": "2026-05-13T10:00:00+00:00",
"phone_number_id": 123,
"data": {
"contact": {
"id": 6789,
"phone_number": "33612345678",
"name": "Jean Dupont",
"country_code": "FR"
},
"message": {
"id": 98765,
"wamid": "wamid.HBgL...",
"type": "text",
"content": "Bonjour, j'ai une question",
"media": null
}
}
}
{
"id": 98766,
"wamid": "wamid.HBgL...",
"type": "image",
"content": "Voici la photo de mon produit",
"media": {
"type": "image",
"url": "https://kanal-api-bucket-1.s3.amazonaws.com/...",
"caption": "Voici la photo de mon produit"
}
}
{
"id": 98767,
"wamid": "wamid.HBgL...",
"type": "video",
"content": null,
"media": {
"type": "video",
"url": "https://kanal-api-bucket-1.s3.amazonaws.com/...",
"caption": null
}
}
{
"id": 98768,
"wamid": "wamid.HBgL...",
"type": "audio",
"content": null,
"media": {
"type": "audio",
"url": "https://kanal-api-bucket-1.s3.amazonaws.com/...",
"caption": null
}
}
{
"id": 98769,
"wamid": "wamid.HBgL...",
"type": "document",
"content": null,
"media": {
"type": "document",
"url": "https://kanal-api-bucket-1.s3.amazonaws.com/...",
"caption": null
}
}
{
"id": 98770,
"wamid": "wamid.HBgL...",
"type": "button_reply",
"content": "Oui, je confirme",
"media": null
}
{
"id": 98771,
"wamid": "wamid.HBgL...",
"type": "list_reply",
"content": "Suivi de commande",
"media": null
}
Pour l'instant, le seul event émis est message.received (message entrant d'un contact). D'autres events sont prévus prochainement (statut de livraison, accusé de lecture, clic sur bouton de template).
type. Les nouveaux types seront ajoutés sans préavis, mais votre intégration ne sera pas impactée si vous ignorez ceux que vous ne traitez pas.Le champ id (format evt_...) est unique pour chaque event. Stockez-le côté serveur pour ignorer les éventuels doublons en cas de retry.
Le champ wamid (identifiant WhatsApp du message) est également unique et stable — utile si vous voulez croiser plusieurs sources de données.
Le champ api_version indique la version du contrat webhook. La version actuelle est 2026-05-13.
Les ajouts non-cassants (nouveaux champs, nouveaux types d'events) sont déployés sans changer la version.
Une nouvelle version sera publiée uniquement en cas de breaking change, avec une période de transition.
Pour rester compatible, votre intégration doit ignorer les champs qu'elle ne connaît pas.
Répondez 200 OK le plus vite possible (sous 5 secondes). Mettez en file le traitement lourd côté serveur.
Filtrez les events par type pour ne traiter que ce qui vous intéresse.
Stockez l'id de chaque event reçu pour éviter les doublons.
Pour répondre au message reçu, utilisez l'endpoint POST /api/v1/messages/send avec le phone_number du contact.
Pour des raisons de compatibilité avec les anciens clients (notamment les notifications mobiles), les champs title, body et text sont également présents à la racine du payload. Ils contiennent un message générique du type « <nom> vient de vous envoyer un nouveau message ». Ignorez-les pour une intégration moderne — toutes les informations utiles sont dans data.