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 traitements côté serveur.
Cliquez sur le nom de votre équipe, puis sur Paramètres.
Ouvrez Développeurs > Webhooks.
Ajoutez l'URL publique de votre serveur. Nous recommandons une URL en HTTPS.
Kanal envoie une requête POST à cette URL à chaque message entrant, avec le corps JSON décrit ci-dessous.
Chaque webhook envoyé suit la même enveloppe :
{
"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": { ... }
}
}Champ | Description |
|---|---|
| Identifiant unique de l'event. |
| 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 le texte exploitable du message (corps texte, légende d'un média, libellé d'un bouton cliqué). Le champ media est rempli uniquement pour les médias (image, vidéo, audio, document). Pour les clics sur bouton et les sélections dans une liste, un objet dédié (button ou list_option) fournit en plus l'identifiant technique de l'option choisie.
{
"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://api.getkanal.com/api/media/messages/98766?signature=...",
"caption": "Voici la photo de mon produit"
}
}L'URL du champ media.url est un lien signé permanent servi par Kanal : vous pouvez le stocker et télécharger à nouveau le média à tout moment.
{
"id": 98767,
"wamid": "wamid.HBgL...",
"type": "video",
"content": null,
"media": {
"type": "video",
"url": "https://api.getkanal.com/api/media/messages/98767?signature=...",
"caption": null
}
}{
"id": 98768,
"wamid": "wamid.HBgL...",
"type": "audio",
"content": null,
"media": {
"type": "audio",
"url": "https://api.getkanal.com/api/media/messages/98768?signature=...",
"caption": null
}
}Les documents reçus (PDF, etc.) envoient un event depuis le 09/08/2026, avec le même format que les autres médias. Le champ media.filename contient le nom du fichier envoyé par le contact.
{
"id": 98769,
"wamid": "wamid.HBgL...",
"type": "document",
"content": null,
"media": {
"type": "document",
"url": "https://api.getkanal.com/api/media/messages/98769?signature=...",
"caption": null,
"filename": "facture-10456.pdf"
}
}{
"id": 98770,
"wamid": "wamid.HBgL...",
"type": "button_reply",
"content": "Oui, je confirme",
"media": null,
"button": {
"id": "4233be9add_button_1",
"title": "Oui, je confirme"
}
}content contient le libellé du bouton cliqué. L'objet button fournit en plus son identifiant technique (button.id), utile pour router la réponse côté serveur sans dépendre du texte affiché. Ce format couvre aussi bien les boutons d'un message interactif que les boutons de réponse rapide d'un template.
{
"id": 98771,
"wamid": "wamid.HBgL...",
"type": "list_reply",
"content": "Suivi de commande",
"media": null,
"list_option": {
"id": "cd593e96a1_row_2",
"title": "Suivi de commande"
}
}Même principe : content contient le titre de la ligne choisie, et list_option.id son identifiant technique.
Les types de messages que Kanal ne gère pas arrivent avec "type": "other" et un content vide.
Le seul event émis est message.received (message entrant d'un contact). Les clics sur les boutons de réponse rapide d'un template arrivent également en message.received, avec le type de message button_reply. Aucun event de statut de livraison ou de lecture n'est envoyé.
type. De nouveaux types pourront être ajoutés : 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. Kanal ne renvoie jamais un event, mais stocker cet identifiant vous protège des doublons que pourrait créer votre propre infrastructure (proxy, file d'attente).
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 changement cassant, 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 en moins de 5 secondes et mettez en file le traitement lourd côté serveur.
Surveillez la disponibilité de votre endpoint : un event non reçu n'est pas renvoyé.
Filtrez les events par type pour ne traiter que ce qui vous intéresse.
Pour répondre au message reçu, utilisez POST /api/v1/messages/send avec le numéro du contact dans le champ to. Voir API Messaging : envoyer des messages et déclencher des automatisations.
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 des textes génériques en anglais : « New message on Kanal » et « <nom> just sent you a new message ». Ignorez-les pour une intégration moderne : toutes les informations utiles sont dans data.