Sign inGet Started

WhatsApp-lijstmenu's

Een lijstmenu verschijnt als een tikbare knop onder een WhatsApp-bericht en klapt open in rijen gegroepeerd in secties, zodat de ontvanger er één kiest uit een langere set opties in plaats van vrije tekst te typen. Gebruik het zodra de keuzelijst langer is dan drie; voor drie of minder zijn antwoordknoppen de eenvoudigere vorm.

How can Goldcrest help today?
Choose a topic
Order support
  • Track my order
    Find your latest delivery update
  • Collect my order
    Check your collection details
  • Talk to our team
    Get help from customer care

Een lijstmenu versturen

Stel interactive.type in op list, met een body_text en een list-object dat button_text en minstens één sectie bevat:

const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  interactive: {
    type: "list",
    body_text: "Which shipping option do you prefer?",
    list: {
      button_text: "Shipping options",
      sections: [
        {
          title: "As soon as possible",
          rows: [{ slug: "priority_express", text: "Priority Mail Express" }],
        },
      ],
    },
  },
});
console.log(msg.id, msg.status);

from is vereist bij elk servicebericht: een nummer dat je werkruimte bezit, geen door Bird beheerd nummer. De volledige structuur voegt een optionele tekstheader, een footer, een citaat van een eerder bericht, een tweede sectie en een rijbeschrijving toe:

Codevoorbeeld
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive": {
    "type": "list",
    "header": { "type": "text", "text": "Choose a shipping option" },
    "body_text": "Which shipping option do you prefer?",
    "footer_text": "Lucky Shrub",
    "list": {
      "button_text": "Shipping options",
      "sections": [
        {
          "title": "As soon as possible",
          "rows": [
            {
              "slug": "priority_express",
              "text": "Priority Mail Express",
              "description": "Next day to 2 days"
            }
          ]
        },
        {
          "title": "I can wait a bit",
          "rows": [
            {
              "slug": "ground_advantage",
              "text": "Ground Advantage",
              "description": "2 to 5 days"
            }
          ]
        }
      ]
    }
  },
  "tags": [{ "name": "flow", "value": "shipping-choice" }],
  "metadata": { "order_id": "A1B2C3" }
}

in_reply_to_message_id citeert een eerder bericht in hetzelfde gesprek. Zie in de hub een bericht citeren om een antwoord te correleren voor hoe resolutie werkt en wat het kan missen.

Een lijstmenu gebruikt list.sections in plaats van het gedeelde knopobject; zie de sectie knoppen in de hub voor hoe de andere typen die vorm wel gebruiken.

Secties en rijen

list.button_text is het label op de knop die het menu opent, maximaal 20 tekens. Tikken opent het menu: elke sectie wordt weergegeven onder zijn eigen title, en elke rij in een sectie toont zijn text-label met het optionele description eronder, in kleiner lettertype. De title van een sectie is vereist, ook als het menu maar één sectie heeft, omdat WhatsApp deze altijd boven de rijen van die sectie toont.

De slug van een rij is je eigen identifier voor die rij, nooit zichtbaar voor de ontvanger. Alleen text wordt in de chat weergegeven, en de slug wordt letterlijk teruggegeven in het antwoord, dezelfde round trip die de hub beschrijft voor knoppen. Er is geen validatie op de tekens in slug: zet er in wat je eigen routering nodig heeft.

Limieten

VeldGrens
Secties per bericht1 tot 10
Rijen per sectie1 tot 10
Rijen over alle secties10, totaal
Sectie-titlevereist, 1 tot 24 tekens
Rij-slugvereist, 1 tot 200 tekens, alle tekens toegestaan
Rij-text (label)vereist, 1 tot 24 tekens, uniek over het hele bericht
Rij-descriptionoptioneel, maximaal 72 tekens
list.button_textvereist, 1 tot 20 tekens
body_textvereist, 1 tot 4096 tekens
footer_textoptioneel, maximaal 60 tekens
header.text1 tot 60 tekens

Twee van deze limieten zijn makkelijk verkeerd te lezen.

Het rijmaximum is tien over alle secties, niet tien per sectie. Elke sectie staat onafhankelijk maximaal 10 rijen toe, maar het bericht als geheel stopt bij 10 rijen totaal. Drie secties van elk 4 rijen slagen voor elke per-sectiecontrole en overschrijden toch het totaal, dat apart van het per-sectieaantal wordt afgedwongen en E15055 retourneert met een bericht dat vermeldt hoeveel rijen de verzending daadwerkelijk aanbood.

body_text is het enige veld dat de volledige 4096 tekens behoudt. Elk ander interactief type beperkt de body tot 1024; een lijstmenu is het enige dat WhatsApp toestaat de volledige lengte te gebruiken, dus kies hiervoor wanneer de keuze meer context nodig heeft dan een kort bericht.

De keuze uitlezen

Een rijtik komt binnen als een eigen inkomend bericht, met interactive_reply:

Codevoorbeeld
{
  "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": "list",
    "list": {
      "slug": "priority_express",
      "text": "Priority Mail Express",
      "description": "Next day to 2 days"
    }
  },
  "created_at": "2026-08-25T09:04:11Z"
}

De slug die je op de gekozen rij hebt ingesteld, komt letterlijk terug, zodat je er direct op kunt vertakken. description is alleen aanwezig als de rij er een bevatte. Je ziet dit antwoord via de berichtenlijst of GET /v1/whatsapp/messages/{id}; zie in de hub een antwoord uitlezen voor het volledige pad.

Limieten en randgevallen

  • Het klantenservicevenster moet open zijn. Een lijstmenu is een servicebericht, alleen bezorgbaar binnen een open venster; zie in de hub klantenservicevenster. De venstercontrole faalt open, dus een 202 is geen bewijs dat het venster daadwerkelijk open was op het moment van verzenden.
  • from moet een nummer zijn dat je werkruimte bezit. Weglaten, of een nummer opgeven dat geen gekoppelde afzender is, wordt geweigerd voordat de verzending wordt aangemaakt.
  • De header is alleen tekst, en een mediaheader mislukt als een generieke fout. Een lijst is het enige interactieve type waarvan de header geen afbeelding, video of document kan bevatten. Toch een mediaheader meesturen levert geen WhatsApp-specifieke foutcode op: het faalt op algemene requestvalidatie, dus een developer die debugt op foutcode ziet alleen dat de request validatie niet doorstond en moet de details lezen om de header te vinden.
  • Het sectie-overschrijdende rijmaximum is de valkuil. Per-sectielimieten en het berichtbrede totaal hebben beide een maximum van 10, dus ze lijken tweemaal hetzelfde getal. Ze zijn niet optelbaar: een menu dat elke per-sectiecontrole doorstaat, kan het totaal alsnog overschrijden, en alleen het totaal wordt afgedwongen.
  • Rijlabels moeten uniek zijn over het hele bericht, niet alleen binnen een sectie. Twee rijen met hetzelfde text-label, zelfs in verschillende secties, worden geweigerd met E15056. Dit is een eigen regel van Bird, niet een die Meta vermeldt: het antwoord noemt het getikte label, dus een duplicaat zou het antwoord ambigu maken, en verschillende slug-waarden eronder lossen dat niet op.
  • Een Meta-side afwijzing buiten de eigen controles van Bird is vaag en kan laat binnenkomen. De controles van Bird op rijaantal en dubbele labels vangen de twee meest voorkomende fouten op voordat er iets wordt aangemaakt. Alles wat Meta daarna afwijst, verschijnt pas na de 202, op de last_error van het bericht, in plaats van bij de verzendaanroep zelf.

Een citaat dat niet resolveert, laat de request mislukken voordat er iets wordt aangemaakt of in rekening gebracht: 404 E15071 wanneer het id geen bericht noemt dat deze werkruimte bezit, 422 E15072 wanneer het een bericht noemt dat niet geciteerd kan worden. Voor de fouten die elke WhatsApp-verzending kan tegenkomen, een gesloten venster, een ontbrekende of ongeldige afzender, of een ongeldige ontvanger, zie in de hub fouten en WhatsApp-berichten versturen.

Volgende stappen