Les messages entrants arrivent de deux façons : poussés en temps réel par webhook, ET stockés pour que vous les relisiez via GET /v1/messages/inbound.
Quand un client écrit à votre numéro WhatsApp, nous faisons deux choses : (1) nous vous le POSTons en temps réel via le webhook message.inbound si vous en avez configuré un, et (2) nous le stockons de façon durable pour que vous puissiez le relire via GET /v1/messages/inbound (conservé selon la fenêtre de rétention par défaut). Recevoir est gratuit — aucun crédit n'est débité. Les médias entrants sont hébergés pour vous : chaque message porte un media_url (GET /v1/media/{id}, redirection vers une URL signée éphémère) en plus du type et du media_id Meta.
Note — Le webhook est instantané ; le pull rattrape
Sans webhook, vous ne recevez rien en temps réel — mais le message est quand même stocké et lisible via GET /v1/messages/inbound (utile depuis un client MCP : lire les reçus puis répondre). Avec webhook, un événement manqué reste rattrapable par le pull. Pour un historique permanent chez vous, écrivez chaque événement de votre côté (voir plus bas).
Renvoie les messages reçus, les plus récents d'abord. Paramètres : number (un phone_number_id, pour un seul de vos numéros ; omis = tous), from (un MSISDN, pour un seul contact), since (timestamp ISO — uniquement après, du plus ancien au plus récent, comme curseur de rattrapage), direction (in ou echo, omis = les deux), limit (1–200, défaut 50). Chaque message porte un champ direction : in (le client vous a écrit) ou echo (message envoyé depuis l'application WhatsApp Business elle-même — Coexistence — pas via l'API).
GET /v1/media/{message_id} — scope messages:read
Redirige (302) vers une URL signée éphémère pour le média d'un message entrant stocké. 404 si le message ne vous appartient pas ou n'a pas de média hébergé (écho, ou hébergement désactivé pour votre compte).
Enregistrez une URL de webhook (dans la console → Webhook). À chaque message reçu, nous y POSTons un événement message.inbound signé HMAC-SHA256 — voir la section Webhooks pour l'enregistrement et la vérification de signature.
Charge utile message.inbound
{
"event": "message.inbound",
"data": {
"from": "+237699000111",
"contact_name": "Jean Mballa",
"number": "1234567890",
"wa_message_id": "wamid…",
"type": "text",
"text": "Bonjour…",
"media_id": null,
"media_url": null,
"timestamp": "2026-08-19T14:05:00Z"
}
}
number est le phone_number_id qui a REÇU le message — repassez-le en from sur POST /v1/messages/reply pour répondre depuis le même numéro. Média (image, audio, document) : hébergé pour les messages entrants — media_url est une URL absolue (GET /v1/media/{id}) qui redirige (302) vers une URL signée éphémère, conservée pour votre fenêtre de rétention ; le texte et les légendes passent intégralement.
Note — Média des échos : métadonnées seules
Un message.inbound porte media_url quand le média est hébergé. Un message.echo (Coexistence, envoyé depuis l'application WhatsApp Business elle-même) reste métadonnées seules — media_id et media_mime, sans media_url — car ce média n'est pas téléchargeable depuis Meta.
Dans les 24h suivant ce message.inbound, répondez en texte libre et gratuit avec POST /v1/messages/reply (voir « Répondre à un client »). Hors de cette fenêtre, ou pour un message à votre initiative, utilisez un template approuvé via POST /v1/messages.
Nous gardons les messages selon une fenêtre de rétention par défaut — assez pour lire et répondre, pas pour servir d'archive définitive. Si vous voulez un historique permanent, un tableau de bord ou une alimentation CRM, gardez votre propre copie : votre endpoint webhook écrit où vous voulez (base de données, file de messages…) à chaque message.inbound reçu. Attention, media_url redirige vers une URL signée éphémère elle aussi conservée pour votre seule fenêtre de rétention — pour une copie permanente des octets d'un média, téléchargez-les vous-même à la réception plutôt que d'enregistrer l'URL. Nous détaillons un pas-à-pas complet avec Firebase/Firestore, mais le même schéma marche avec Supabase ou toute autre base : recevez le webhook, vérifiez sa signature, écrivez chez vous.
Concrètement, cette fenêtre par défaut est de 30 jours : au-delà, les messages sont définitivement supprimés par une purge quotidienne — GET /v1/storage vous indique votre volume stocké et votre rétention effective.