Sign inGet started

Carrousels média WhatsApp

Un carrousel média est un ensemble de deux à dix cartes que le destinataire fait défiler côte à côte, chacune avec sa propre image ou vidéo, son propre texte court et ses propres boutons. Utilisez-le pour montrer plusieurs éléments à la fois, par exemple une poignée de produits, plutôt que d'envoyer un message par élément.

Envoyer un carrousel

Définissez interactive.type à carousel, avec un body_text au niveau du message et un tableau cards de 2 à 10 entrées :
const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  interactive: {
    type: "carousel",
    body_text: "Here are two of our latest arrivals, each under $25:",
    cards: [
      {
        header: { type: "image", url: "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/blue-echeveria" },
          },
        ],
      },
      {
        header: { type: "image", url: "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        buttons: [
          {
            type: "cta_url",
            cta_url: { text: "Buy now", url: "https://shop.example.com/zebra-haworthia" },
          },
        ],
      },
    ],
  },
});
console.log(msg.id, msg.status);
from est requis sur chaque message de service : un numéro appartenant à votre espace de travail, pas un numéro géré par Bird. La forme complète ajoute le texte propre à une carte, un second bouton de réponse rapide et une citation d'un message antérieur :
Exemple de code
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive": {
    "type": "carousel",
    "body_text": "Here are two of our latest arrivals, each under $25:",
    "cards": [
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/blue-echeveria.jpeg" },
        "body_text": "Blue Echeveria. Powdery blue leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-echeveria", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-echeveria", "text": "Details" } }
        ]
      },
      {
        "header": { "type": "image", "url": "https://cdn.example.com/plants/zebra-haworthia.jpeg" },
        "body_text": "Zebra Haworthia. White stripes on deep green leaves.",
        "buttons": [
          { "type": "quick_reply", "quick_reply": { "slug": "buy-haworthia", "text": "Buy" } },
          { "type": "quick_reply", "quick_reply": { "slug": "info-haworthia", "text": "Details" } }
        ]
      }
    ]
  },
  "tags": [{ "name": "category", "value": "catalog" }],
  "metadata": { "order_id": "A-1" }
}
in_reply_to_message_id cite un message antérieur dans la même conversation. Consultez la section citer un message pour corréler une réponse du hub pour comprendre comment la résolution fonctionne et ce qu'elle peut manquer.
Un carrousel n'accepte ni en-tête ni pied de page au niveau du message : le body_text du message est le seul texte au-dessus des cartes. Consultez la section boutons du hub pour la forme de bouton partagée que les cartes de ce type réutilisent.

Cartes

Chaque carte possède son propre en-tête média, son propre texte court et ses propres boutons :
  • header est requis sur chaque carte, et il est image ou video uniquement : pas de texte ni d'en-tête document, contrairement aux autres types interactifs.
  • body_text est optionnel. Il se place sous le média de la carte, limité à une longueur inférieure à celle du corps d'un message, et autorise au maximum deux sauts de ligne.
  • buttons est requis : soit un bouton cta_url, soit jusqu'à trois boutons quick_reply, jamais un mélange sur la même carte.
Les cartes s'affichent de gauche à droite dans l'ordre où elles apparaissent dans le tableau cards. Une carte n'a ni pied de page ni champ d'index propre ; sa position dans le tableau est sa position dans le carrousel.

Chaque carte porte les mêmes boutons

Chaque carte d'un carrousel doit porter les mêmes types de boutons, le même nombre et le même ordre. Un carrousel où la carte 1 a un bouton cta_url et la carte 2 a deux boutons quick_reply est refusé, tout comme un carrousel où chaque carte a deux boutons quick_reply mais dans un ordre différent.
La raison tient à la façon dont WhatsApp affiche le message : un carrousel est une vue carte unique avec une mise en page partagée, pas un ensemble de cartes disposées indépendamment. Une carte avec une rangée de boutons différente casserait cette mise en page partagée, donc WhatsApp exige que chaque carte soit identique et Bird le vérifie avant que l'envoi ne soit créé ou facturé. Une incohérence renvoie E15059.
Les libellés de boutons obéissent à une règle distincte, dont la portée diffère : un libellé doit être unique au sein d'une carte, pas dans l'ensemble du carrousel. "Buy now" sur chacune des dix cartes est valide ; "Buy now" deux fois sur la même carte renvoie E15056.

Limites

ChampLimite
cards2 à 10 entrées
header de la carterequis sur chaque carte ; image ou video uniquement
header.url de la carterequis, pas de longueur maximale
body_text de la carteoptionnel, 1 à 160 caractères, 2 sauts de ligne au maximum
buttons de la carte1 à 3 entrées : un cta_url, ou jusqu'à trois quick_reply, jamais mélangés
Libellé de bouton (quick_reply.text, cta_url.text)requis, 1 à 20 caractères, unique au sein de la carte
quick_reply.slugrequis, 1 à 256 caractères
cta_url.urlrequis, 1 à 2 000 caractères
body_text du messagerequis, 1 à 1 024 caractères
En-tête du message, pied de pagenon autorisé sur un carrousel : pas de header, pas de footer_text
Bird limite les boutons quick_reply à trois par carte. Meta lui-même n'indique aucune limite numérique, seulement qu'une carte accepte soit un bouton lien, soit un ou plusieurs boutons de réponse, donc ce plafond est propre à Bird, pas à WhatsApp.

Lire la réponse

Seul un bouton de carte quick_reply produit une réponse. Un appui dessus arrive comme un message entrant distinct, contenant interactive_reply :
Exemple de code
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+16505551234" },
  "to": { "phone_number": "+13124495648" },
  "status": "received",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive_reply": {
    "type": "button",
    "button": {
      "slug": "buy-echeveria",
      "text": "Buy"
    }
  },
  "created_at": "2026-08-25T09:04:11Z"
}
Le slug que vous avez défini sur le bouton appuyé revient tel quel dans interactive_reply.button.slug, la même forme qu'un appui sur un bouton de réponse. Vous voyez cette réponse via la liste de messages ou GET /v1/whatsapp/messages/{id} ; consultez la section lire une réponse du hub pour le parcours complet.
Un bouton cta_url sur une carte ouvre son lien dans le navigateur du destinataire et ne renvoie rien, comme un bouton lien autonome.

Carrousels libres et carrousels de templates

Cette page couvre le carrousel libre que vous envoyez en ligne avec interactive.type: "carousel", livrable uniquement à l'intérieur d'une fenêtre de service client ouverte et jamais examiné par Meta. Templates WhatsApp possède son propre carrousel distinct : un composant de template créé une fois, soumis à Meta pour approbation, et envoyé par slug comme tout autre template, y compris en dehors de la fenêtre. Les deux partagent le mot "carousel" et la plage de 2 à 10 cartes de Meta, et rien d'autre : des formats filaires différents, des parcours de validation différents, et le nombre de cartes d'un carrousel de template est fixé à l'approbation du template plutôt que choisi à chaque envoi. Si vous parcourez les templates et voyez "carousel", il s'agit du type template, pas de cette page.

Limites et cas particuliers

  • La fenêtre de service client doit être ouverte. Un carrousel est un message de service, livrable uniquement à l'intérieur d'une fenêtre ouverte ; consultez la section fenêtre de service client du hub. La vérification de la fenêtre échoue de manière permissive, donc un 202 ne prouve pas que la fenêtre était réellement ouverte au moment de l'envoi.
  • from doit être un numéro appartenant à votre espace de travail. L'omettre ou nommer un numéro qui n'est pas un expéditeur connecté est rejeté avant la création de l'envoi.
  • Le média d'une carte doit être accessible publiquement au moment où l'envoi est dispatché. Bird ne stocke ni ne proxifie le fichier : WhatsApp récupère le url de chaque carte lui-même, au moment de l'envoi, donc une URL signée doit rester valide au-delà de l'envoi.
  • Une URL de média de carte que WhatsApp ne peut pas récupérer est acceptée, puis échoue de manière asynchrone, et est quand même facturée. La validation de requête de Bird vérifie uniquement que le url d'une carte est une URI bien formée, pas que WhatsApp peut l'atteindre ni qu'elle utilise https. Un fichier trop volumineux, un 404, un hôte non résolvable ou un type de fichier incorrect reviennent tous comme un 202 à l'acceptation, puis whatsapp.accepted puis whatsapp.sent puis whatsapp.failed, avec media_rejected sur le last_error du message et le coût de l'envoi déjà facturé sans possibilité de remboursement. Testez l'URL de chaque carte avant l'envoi, car une URL cassée n'est détectée qu'après coup.
  • Chaque carte doit porter les mêmes boutons. Voir Chaque carte porte les mêmes boutons ci-dessus ; c'est la seule règle de carrousel que le schéma de requête ne peut pas exprimer seul, donc elle est vérifiée séparément et renvoie E15059 plutôt qu'une erreur de validation générique.
  • Pas d'en-tête ni de pied de page au niveau du message. Le seul texte d'un carrousel au-dessus des cartes est body_text ; il n'y a pas d'emplacement pour des mentions légales comme les autres types utilisent footer_text.
  • La réponse ne contient pas d'index de carte. L'appui sur quick_reply d'une carte ne rapporte que {slug, text}, la même forme qu'un appui sur un bouton de réponse, sans champ indiquant de quelle carte il provient. Si vous devez savoir quelle carte a été appuyée, encodez la carte dans le slug de chaque bouton, par exemple buy-echeveria plutôt qu'un simple buy.
  • Un bouton de carte cta_url ne génère aucun événement entrant. Si vous devez savoir qu'une carte a été utilisée, utilisez des boutons quick_reply sur cette carte à la place, ou suivez le clic sur votre propre URL de destination.
Au-delà de E15059, la seule erreur interactive spécifique à un carrousel est E15056 pour un libellé de bouton dupliqué sur une carte. Une citation qui ne se résout pas fait échouer la requête avant que quoi que ce soit ne soit créé ou facturé : 404 E15071 quand l'id ne désigne aucun message détenu par cet espace de travail, 422 E15072 quand il désigne un message qui ne peut pas être cité. Pour les erreurs que tout envoi WhatsApp peut rencontrer, une fenêtre fermée, un expéditeur manquant ou invalide, ou un destinataire invalide, consultez les sections erreurs et Envoi de messages WhatsApp du hub.

Étapes suivantes