# Webhook multicanal : WhatsApp, email et SMS en un seul ?

> Chaque réponse WhatsApp, email et SMS dans un seul webhook JSON signé, depuis votre numéro, votre boîte et votre téléphone. 1 handler au lieu de 3 formats.

Source: https://unlimitedmessaging.app/fr/articles/one-webhook-whatsapp-email-sms

Webhook multicanal

# Chaque réponse, sur chaque canal,  
_dans un seul webhook._

WhatsApp depuis votre numéro, email depuis votre boîte, SMS depuis votre téléphone : un seul endpoint les reçoit tous dans la même enveloppe JSON signée. Un handler alimente votre boîte de réception, votre agent IA ou votre CRM.

[Créer un compte gratuit](https://app.unlimitedmessaging.app)[Voir les offres payantes](https://unlimitedmessaging.app/fr/pricing)

La réponse courte

## Un seul webhook peut-il recevoir WhatsApp, email et SMS ?

Oui. Unlimited Messaging envoie chaque message reçu sur votre numéro WhatsApp relié, votre boîte mail connectée et la SIM de votre téléphone Android vers une seule URL, sous le même événement, message.received, signé selon [Standard Webhooks](https://www.standardwebhooks.com). L'enveloppe ne change jamais ; data.channel.type indique WHATSAPP, EMAIL ou SMS. Les webhooks sont inclus dans les offres payantes Medium et Max.

Assemblée à partir de fournisseurs séparés, la même boîte de réception demande trois intégrations. La Cloud API de Meta envoie du JSON imbriqué signé en X-Hub-Signature-256 après une poignée de main hub.challenge. Twilio envoie SMS et WhatsApp en paramètres form-encoded signés en HMAC-SHA1\. SendGrid Inbound Parse envoie du multipart/form-data pour un nom d'hôte dont vous avez déplacé le MX. Trois parsers, trois vérifications de signature, trois idées de ce qu'est une conversation.

Ici, les canaux sont des services à côté d'une seule API, et cette API annonce chaque message de la même façon : id, direction, content, sender, sentAt, la conversation (un chat ou un groupe WhatsApp, la racine d'un fil d'emails, un numéro SMS) et le compte qui l'a reçu. L'email ajoute subject, html et attachments ; WhatsApp ajoute les médias, les groupes, les réactions et les modifications. Les règles de livraison sont communes : répondre 2xx en moins de 10 secondes, 8 essais sur un peu plus de 3 jours, dédupliquer sur eventId.

Les réponses repartent des mêmes identités. replyToMessageId répond sur place dans un chat WhatsApp ou un fil d'emails ; une réponse SMS désigne la SIM. Vos clients voient votre numéro et votre adresse, jamais ceux d'un fournisseur.

À lire aussi : [envoyer email et WhatsApp en une seule requête API](https://unlimitedmessaging.app/fr/articles/email-whatsapp-single-api-request), et [réunir la prospection WhatsApp et email dans une seule boîte](https://unlimitedmessaging.app/fr/articles/sales-whatsapp-email-one-inbox).

![Illustration : deux serveurs qui échangent des événements webhook.](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fone-webhook-whatsapp-email-sms-fr.png&w=3840&q=75)

Définition
Webhook multicanal

Un endpoint HTTP unique qui reçoit les messages entrants de plusieurs canaux (WhatsApp, email, SMS) dans un même format, avec un champ qui nomme le canal : un seul handler sert toutes les conversations.

Aussi recherché comme webhook de messagerie unifiée, webhook omnicanal ou API de boîte de réception omnicanale.

[Source : spécification Standard Webhooks↗](https://www.standardwebhooks.com)

Les événements

## À quoi ressemble le payload du webhook multicanal ?

Le même événement message.received sur chaque canal. Ce qui change : data.channel.type et quelques champs propres au canal.

1. 01  
### Commun à tous les canaux  
type, eventId, occurredAt ; data.message avec id, externalId, direction, fromMe, content, sentAt, receivedAt, sender, senderId ; data.channel avec type, account (id, name) et conversation (id, isGroup, address).
2. 02  
### WHATSAPP  
Médias (mediaUrl, mediaType, mimeType), localisations, réponses citées (replyTo), groupes (participant, conversation.participants), plus message.reaction, message.edited et message.deleted.
3. 03  
### EMAIL  
subject, html (non fiable, à nettoyer), attachments (20 par email au plus), conversation.id égal à la racine du fil et replyTo au message auquel on répond.
4. 04  
### SMS  
Texte uniquement. conversation.id vaut null : regroupez par sender. Messages reçus après la connexion de l'application Android.
5. 05  
### Autour des messages  
message.sent et message.status suivent ce que vous envoyez sur les trois canaux ; account.status\_changed signale un numéro, une boîte ou une SIM qui décroche.

Trois canaux, une enveloppeJSON

```
// WhatsApp
{ "type": "message.received", "eventId": "whd_6f1c...", "occurredAt": "2026-11-09T10:00:01.000Z",
  "data": {
    "message": { "id": "msg_0e55...", "direction": "IN", "content": "Is my order ready?",
                 "sender": "+447700900123", "senderName": "Lea", "sentAt": "2026-11-09T10:00:00.000Z" },
    "channel": { "type": "WHATSAPP", "account": { "id": "acc_373b...", "name": "Support" },
                 "conversation": { "id": "447700900123@s.whatsapp.net", "isGroup": false,
                                   "address": "+447700900123" } } } }

// Email: same envelope, plus subject, html and attachments
{ "type": "message.received", "eventId": "whd_9a4f...", "occurredAt": "2026-11-09T14:05:12.000Z",
  "data": {
    "message": { "id": "msg_3f8a...", "direction": "IN", "content": "Signed quote attached.",
                 "sender": "claire@example.com", "subject": "Re: Quote #1042",
                 "html": "<p>Signed quote attached.</p>", "attachments": [ { "filename": "quote.pdf" } ] },
    "channel": { "type": "EMAIL", "account": { "id": "acc_8b2e...", "name": "sales@yourcompany.example" },
                 "conversation": { "id": "quote-1042.20261108@yourcompany.example", "isGroup": false,
                                   "address": "claire@example.com" } } } }

// SMS: text only, no conversation id
{ "type": "message.received", "eventId": "whd_2b9e...", "occurredAt": "2026-11-09T08:42:06.000Z",
  "data": {
    "message": { "id": "msg_7d2c...", "direction": "IN", "content": "Running 10 min late, sorry!",
                 "sender": "+447700900456", "sentAt": "2026-11-09T08:42:03.000Z" },
    "channel": { "type": "SMS", "account": { "id": "acc_5e8d...", "name": "Front desk SIM" },
                 "conversation": { "id": null, "isGroup": false, "address": "+447700900456" } } } }
```

Des corps message.received abrégés, d'après le schéma publié, un par canal. L'événement complet porte tous les champs listés à gauche.

Mise en place

## Comment écrire un seul handler pour tous les canaux ?

Reliez les trois canaux une fois, enregistrez un endpoint, et ne différenciez que là où un canal diffère vraiment.

1. 01  
### Reliez vos canaux  
Scannez un QR code pour WhatsApp, connectez votre boîte en IMAP/SMTP, installez l'application Android pour le SMS. Chacun devient un compte.
2. 02  
### Enregistrez un seul endpoint  
POST /webhooks avec votre URL et vos eventTypes, ou ajoutez-le sur la page Webhooks du tableau de bord. Sans accountIds, il couvre tous les comptes, même futurs.
3. 03  
### Vérifiez une fois, différenciez tard  
Une vérification de signature, un upsert sur eventId, une ligne de boîte de réception. Seul l'appel de réponse diffère : replyToMessageId pour WhatsApp et l'email, la SIM pour le SMS.

POST /webhookscurl

```
curl https://api.unlimitedmessaging.app/webhooks \
  -H "Authorization: Bearer $UM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/um",
    "eventTypes": ["message.received", "message.status", "account.status_changed"],
    "description": "Every reply, every channel"
  }'

# No accountIds: the endpoint covers every WhatsApp number, mailbox and SIM you have,
# including ones linked later. The response carries "secret": "whsec_..." once.
```

Il n'existe pas d'option « tous les événements » : listez les types voulus. Un type ajouté plus tard n'est jamais activé sur les endpoints existants ; envoyez la liste complète avec PATCH /webhooks/{id} pour en ajouter un.

app/api/webhooks/um/route.tsNext.js route handler

```
// app/api/webhooks/um/route.ts (Next.js App Router)
import crypto from 'node:crypto';
import { UnlimitedMessagingApiClient } from '@unlimited-messaging/sdk';

const um = new UnlimitedMessagingApiClient({ token: process.env.UM_API_KEY! });
const key = Buffer.from(process.env.UM_WEBHOOK_SECRET!.replace(/^whsec_/, ''), 'base64');

// Standard Webhooks: HMAC-SHA256 of "id.timestamp.rawBody", base64.
function verify(raw: string, id: string, ts: string, header: string) {
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = crypto.createHmac('sha256', key).update(`${id}.${ts}.${raw}`).digest('base64');
  return header.split(' ').some((entry) => {
    const sig = entry.startsWith('v1,') ? entry.slice(3) : '';
    return sig.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  });
}

export async function POST(req: Request) {
  const raw = await req.text();
  const h = req.headers;
  if (!verify(raw, h.get('webhook-id') ?? '', h.get('webhook-timestamp') ?? '',
    h.get('webhook-signature') ?? '')) {
    return new Response('bad signature', { status: 401 });
  }

  const event = JSON.parse(raw);
  if (event.type !== 'message.received') return new Response(null, { status: 200 });

  const { message: m, channel } = event.data;
  // One inbox row, whatever the channel (upsert on eventId: delivery is at least once).
  await inbox.upsert({
    eventId: event.eventId,
    channel: channel.type,                       // WHATSAPP | EMAIL | SMS
    from: m.sender ?? m.senderId,                // +E164 or email address
    thread: channel.conversation.id ?? m.sender, // SMS has no conversation id
    subject: m.subject ?? null,
    text: m.content,
    at: m.sentAt,                                // order on this, not on arrival
  });

  const answer = await draftReply(m.content);    // your LLM call, or null for a human
  if (answer) {
    if (channel.type === 'SMS') {
      await um.messages.messageSend({
        to: { phone: m.sender },
        channels: [{ channel: 'SMS', accountId: channel.account.id }],
        text: answer,
      });
    } else {
      // WhatsApp and email: same chat or same thread, same number or mailbox.
      await um.messages.messageSend({ replyToMessageId: m.id, text: answer });
    }
  }
  return new Response(null, { status: 200 }); // within 10 s; queue slow work
}
```

inbox et draftReply sont à vous (une table, un appel LLM). La vérification suit le schéma Standard Webhooks documenté, identique pour tous les canaux.

Vibe coding

## Vous codez avec Cursor, Claude Code, Lovable ou Bolt ? Collez ceci

Assez de contexte pour que votre éditeur IA construise toute la route de la boîte unifiée en une passe.

Prompt à copier

Add a unified inbox to this app with Unlimited Messaging: WhatsApp (my number), email (my mailbox) and SMS (my Android phone) all arrive on ONE webhook.

1. Create a POST route at /api/webhooks/um that reads the RAW body.
2. Verify the Standard Webhooks signature: key = base64-decode(UM_WEBHOOK_SECRET without "whsec_"); expected = base64(HMAC-SHA256(key, `${webhook-id}.${webhook-timestamp}.${rawBody}`)); accept if any space-separated entry of the webhook-signature header equals `v1,${expected}` (constant-time compare); reject timestamps more than 5 minutes off; return 401 otherwise.
3. On type "message.received", upsert one row keyed on body.eventId: channel = data.channel.type (WHATSAPP | EMAIL | SMS), from = data.message.sender ?? data.message.senderId, thread = data.channel.conversation.id ?? data.message.sender, subject = data.message.subject, text = data.message.content, at = data.message.sentAt (order on this, never on arrival).
4. Build an inbox page listing threads across channels with a channel badge.
5. Replies: install @unlimited-messaging/sdk, read UM_API_KEY from env. WhatsApp and email: `client.messages.messageSend({ replyToMessageId: data.message.id, text })`. SMS: `client.messages.messageSend({ to: { phone: sender }, channels: [{ channel: 'SMS', accountId: data.channel.account.id }], text })`.
6. Return 200 within 10 seconds; queue slow work. Put UM_API_KEY and UM_WEBHOOK_SECRET in .env and .env.example.

Docs: https://docs.unlimitedmessaging.app (Webhooks). Register with POST https://api.unlimitedmessaging.app/webhooks and eventTypes ["message.received", "message.status", "account.status_changed"].

Ce que l'on construit

## Que construire avec un seul webhook pour tous les canaux ?

Trois projets qui demandent trois intégrations ailleurs, et un seul handler ici.

### Une boîte de support multicanale

Une liste de conversations, un badge par canal, des réponses envoyées depuis votre numéro ou votre adresse dans le même fil. Ajoutez message.status pour afficher distribué et lu quand le canal le signale.

### Un répondeur IA

Donnez content à Claude ou GPT avec l'historique de la conversation, renvoyez la réponse sur le canal d'origine, passez la main à un humain sur mot-clé ou en cas de doute.

### Synchro CRM

Rattachez chaque message au contact par téléphone ou adresse email, quel que soit le canal, avec sentAt pour la chronologie.

1. 01  
### Bascule de canal  
Pas de réponse sur WhatsApp au bout d'un jour ? Relancez par email ou SMS ; le même POST /message peut envoyer sur trois canaux à la fois.
2. 02  
### Supervision  
account.status\_changed sur les trois canaux vous dit quand un numéro, une boîte ou un téléphone cesse de relayer.
3. 03  
### Flux no-code  
Pointez le webhook vers n8n, Make ou Zapier et aiguillez sur data.channel.type.

Le tableau

## Une boîte, trois façons : Twilio, une pile maison ou Unlimited Messaging

Ce qu'il faut pour recevoir les réponses WhatsApp, email et SMS dans le même code.

__Une boîte, trois façons : Twilio, une pile maison ou Unlimited Messaging__
| [Twilio + SendGrid](https://www.twilio.com/docs/messaging/guides/webhook-request)Un fournisseur, plusieurs produits | [Meta + service de parsing + fournisseur SMS](https://developers.facebook.com/docs/graph-api/webhooks/getting-started)Fait maison | Unlimited MessagingUn webhook, offres payantes                                        |                                                                |
| ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Formats de payload                                                                                                  | Form-encoded pour SMS et WhatsApp, multipart pour l'email                                                                         | JSON de Meta, format du fournisseur, multipart ou JSON pour l'email                   | Une seule enveloppe JSON                                       |
| Vérifications de signature                                                                                          | X-Twilio-Signature (HMAC-SHA1), plus la protection propre à l'endpoint de parsing                                                 | X-Hub-Signature-256 pour Meta, une par autre fournisseur                              | Une seule vérification Standard Webhooks                       |
| Identités vues par vos clients                                                                                      | Numéros loués chez Twilio, un expéditeur WhatsApp enregistré                                                                      | Un numéro basculé sur la Cloud API, un numéro SMS loué                                | Votre numéro, votre boîte et votre SIM                         |
| Mise en place avant le premier message                                                                              | Achat de numéro, enregistrement de l'expéditeur WhatsApp, MX                                                                      | App Meta et portefeuille business, MX, location de numéro                             | Scan de QR code, mot de passe de la boîte, application Android |
| Frais par message                                                                                                   | 0,0083 $ par segment SMS reçu aux États-Unis, 0,005 $ par message WhatsApp plus frais Meta                                        | Frais Meta au-delà de 1 000 réponses de service par numéro et par mois, frais par SMS | Aucun ; webhooks avec Medium ou Max                            |
| Statut officiel                                                                                                     | WhatsApp Business Platform officielle                                                                                             | WhatsApp Business Platform officielle                                                 | WhatsApp par le protocole non officiel des appareils connectés |

Vérifié le 9 novembre 2026 sur les pages Twilio (webhooks, tarifs SMS et WhatsApp), la documentation Meta (webhooks, tarifs) et le guide Inbound Parse de SendGrid (liens dans les sources).

Les contreparties

## Quelles sont les limites d'un webhook unifié sur vos propres canaux ?

Un seul format supprime le code de colle. Chaque canal garde sa nature.

1. 01  
### Les webhooks sont payants  
L'envoi sur les trois canaux est gratuit sur toutes les offres, et les messages reçus s'affichent dans la boîte de l'application web. Les pousser vers votre serveur demande Medium (19 € par mois, ou 17 € par mois en annuel) ou Max.
2. 02  
### WhatsApp est un appareil connecté  
Le numéro est relié comme WhatsApp Web, par un protocole non officiel : le spam le fait restreindre, et WhatsApp déconnecte les appareils reliés si le téléphone principal reste hors ligne 14 jours.
3. 03  
### Le SMS demande un téléphone Android  
La SIM relaie via l'application Android gratuite (8.0 ou plus récent), qui doit rester allumée et connectée. Texte uniquement, et seulement les SMS reçus après la connexion.
4. 04  
### L'email lit la boîte de réception  
Boîtes IMAP uniquement pour l'instant (Gmail avec un mot de passe d'application, votre domaine, la plupart des hébergeurs) ; pas encore d'Outlook ni de Microsoft 365\. Le courrier classé en spam ou dans d'autres dossiers n'est pas vu.
5. 05  
### Tous les champs n'existent pas sur tous les canaux  
Le SMS n'a ni identifiant de conversation ni accusé de lecture, l'email n'a pas de réactions, WhatsApp n'a pas d'objet. Codez sur les champs communs et traitez le reste comme optionnel.

Comment choisir

### Webhook unifié ou fournisseurs séparés ?

Il vous faut le badge WhatsApp officiel, des campagnes de modèles à grande échelle, des numéros courts ou des milliers d'adresses email générées : assemblez des fournisseurs officiels et budgétez chacun. Vous voulez réunir les réponses que vos clients envoient déjà à votre numéro, votre adresse et votre téléphone, avec un seul handler et des réponses depuis les mêmes identités : reliez les trois et abonnez un endpoint à message.received.

FAQ

## Questions sur le webhook multicanal

Oui. Avec Unlimited Messaging, un endpoint abonné à message.received reçoit les messages de votre numéro WhatsApp relié, de votre boîte mail et de votre SIM Android dans la même enveloppe JSON signée ; data.channel.type indique le canal. Les webhooks demandent l'offre Medium ou Max.

data.channel.type vaut WHATSAPP, EMAIL ou SMS, et data.channel.account désigne le numéro, la boîte ou la SIM qui a reçu le message. L'email ajoute subject, html et attachments.

Utilisez data.channel.conversation.id : le chat ou le groupe WhatsApp, ou le Message-ID racine d'un fil d'emails. Le SMS n'a pas d'identifiant de conversation : regroupez par sender. Pour fusionner une personne entre canaux, rapprochez son numéro et son adresse email dans votre CRM.

Signés selon Standard Webhooks (HMAC-SHA256 sur id.timestamp.rawBody, secret whsec\_). Retentés sur 429, 5xx, délai dépassé et erreur réseau après 30 s, 2 min, 10 min, 1 h, 6 h, 1 jour et 2 jours : 8 essais sur un peu plus de 3 jours.

Oui. Passez content à votre modèle et envoyez la réponse avec POST /message : replyToMessageId pour WhatsApp et l'email (même chat, même fil), ou to.phone avec une entrée channels SMS et l'accountId de la SIM.

Ni l'un ni l'autre. Un endpoint sans accountIds couvre tous vos comptes, y compris ceux reliés plus tard. Ajoutez accountIds quand une équipe ne doit en voir qu'une partie.

Oui : message.received pour l'entrant, message.sent pour ce que vous envoyez par l'API, et message.self\_sent pour ce que vous tapez sur votre téléphone WhatsApp. La boîte montre les deux côtés.

Non. Unlimited Messaging ne facture aucun frais par message, sur aucun canal ; les webhooks viennent avec l'offre Medium ou Max. Les réponses SMS comptent sur votre forfait.

Sources

## Sources & références

Pour vérifier par vous-même les informations de cet article :

1. [01Spécification Standard Webhooks↗standardwebhooks.com](https://www.standardwebhooks.com)
2. [02Getting started with webhooks (hub.challenge, X-Hub-Signature-256)↗Meta for Developers](https://developers.facebook.com/docs/graph-api/webhooks/getting-started)
3. [03Tarifs de la WhatsApp Business Platform↗Meta for Developers](https://developers.facebook.com/docs/whatsapp/pricing)
4. [04Incoming message webhook request (form-encoded)↗Twilio Docs](https://www.twilio.com/docs/messaging/guides/webhook-request)
5. [05Webhooks security (X-Twilio-Signature, HMAC-SHA1)↗Twilio Docs](https://www.twilio.com/docs/usage/webhooks/webhooks-security)
6. [06Tarifs SMS aux États-Unis↗Twilio](https://www.twilio.com/en-us/sms/pricing/us)
7. [07Tarifs WhatsApp (0,005 $ par message, entrant ou sortant)↗Twilio](https://www.twilio.com/en-us/whatsapp/pricing)
8. [08Setting up the Inbound Parse webhook (MX, multipart/form-data)↗Twilio SendGrid Docs](https://www.twilio.com/docs/sendgrid/for-developers/parsing-email/setting-up-the-inbound-parse-webhook)
9. [09À propos des appareils connectés (déconnexion après 14 jours sans le téléphone principal)↗Pages d'aide WhatsApp](https://faq.whatsapp.com/378279804439436)
10. [10Référence de l'API Unlimited Messaging - Webhooks↗Unlimited Messaging](https://docs.unlimitedmessaging.app)

![Ilian, ingénieur logiciel senior](https://ilianazz.com/images/iliazz.png)

Écrit par

[Ilian](https://unlimitedmessaging.app/fr/authors/ilian) · Senior Software Engineer

Ingénieur logiciel senior, il fonde et dirige plusieurs sociétés tech. Il conçoit des produits autour des API de messagerie, de l’automatisation et de l’intégration de l’IA, et partage ici ce qu’il apprend en construisant.

[Voir le profil LinkedIn↗](https://www.linkedin.com/in/ilianAzz/)Mis à jour le 9 novembre 2026

![](https://unlimitedmessaging.app/assets/logos/whatsapp.svg)![](https://unlimitedmessaging.app/assets/logos/email.svg)![](https://unlimitedmessaging.app/assets/logos/sms.svg)

## Trois canaux, un seul handler.

Créez un compte, reliez votre WhatsApp, votre boîte mail et votre téléphone Android, et activez les webhooks avec Medium ou Max. L'envoi reste gratuit sur toutes les offres.

[Créer un compte gratuit→](https://app.unlimitedmessaging.app)

Articles similaires
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fwhatsapp-webhook-incoming-messages-fr.png&w=3840&q=75)Webhook WhatsApp sans validation Meta : est-ce possible ?Les messages WhatsApp reçus sur votre propre numéro, poussés vers votre serveur en JSON signé. Événements, payload, handler Node.js.](https://unlimitedmessaging.app/fr/articles/whatsapp-webhook-incoming-messages)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Femail-inbound-webhook-fr.png&w=3840&q=75)Webhook email entrant sans toucher à vos MX : comment ?Votre propre boîte mail vers un webhook : objet, HTML, pièces jointes et fils en JSON signé, avec réponses depuis la même adresse.](https://unlimitedmessaging.app/fr/articles/email-inbound-webhook)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fsms-webhook-incoming-sms-fr.png&w=3840&q=75)Webhook SMS sur votre propre numéro : faut-il Twilio ?Les SMS reçus par votre propre SIM, envoyés en JSON signé par une app Android gratuite. Sans numéro loué, sans frais par SMS reçu.](https://unlimitedmessaging.app/fr/articles/sms-webhook-incoming-sms)
