WhatsApp-Listenmenüs
Ein Listenmenü erscheint als antippbarer Button unter einer WhatsApp-Nachricht und klappt zu Zeilen auf, die in Sektionen gruppiert sind. So wählt der Empfänger aus einer längeren Liste von Optionen, statt Freitext einzugeben. Verwenden Sie es, wenn die Auswahlliste mehr als drei Einträge hat; für drei oder weniger sind Antwort-Buttons die einfachere Variante.
- Track my orderFind your latest delivery update
- Collect my orderCheck your collection details
- Talk to our teamGet help from customer care
Listenmenü senden
Setzen Sie interactive.type auf list, mit einem body_text- und einem list-Objekt, das button_text und mindestens eine Sektion enthält:
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);msg = client.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"}],
}
],
},
},
)
print(msg.id, msg.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+16505551234",
From: "+13124495648",
Interactive: &bird.WhatsAppInteractiveSend{
Type: "list",
BodyText: "Which shipping option do you prefer?",
List: &bird.WhatsAppInteractiveListSend{
ButtonText: "Shipping options",
Sections: []bird.WhatsAppInteractiveListSectionSend{
{
Title: "As soon as possible",
Rows: []bird.WhatsAppInteractiveListRowSend{
{Slug: "priority_express", Text: "Priority Mail Express"},
},
},
},
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$interactive = (new WhatsAppMessageSendRequestInteractive())
->setType('list')
->setBodyText('Which shipping option do you prefer?')
->setList(
(new WhatsAppInteractiveSendList())
->setButtonText('Shipping options')
->setSections([
(new WhatsAppInteractiveListSectionSend())
->setTitle('As soon as possible')
->setRows([
(new WhatsAppInteractiveListRowSend())
->setSlug('priority_express')
->setText('Priority Mail Express'),
]),
]),
);
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
interactive: $interactive,
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--from +13124495648 \
--interactive '{"body_text":"Which shipping option do you prefer?","list":{"button_text":"Shipping options","sections":[{"rows":[{"slug":"priority_express","text":"Priority Mail Express"}],"title":"As soon as possible"}]},"type":"list"}' \
--to +16505551234curl -X POST "https://{region}.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"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" }]
}
]
}
}
}'from ist bei jeder Service-Nachricht erforderlich: eine Nummer, die Ihr Workspace besitzt, keine von Bird verwaltete. Die vollständige Struktur fügt einen optionalen Text-Header, einen Footer, ein Zitat einer früheren Nachricht, eine zweite Sektion und eine Zeilenbeschreibung hinzu:
{
"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 zitiert eine frühere Nachricht in derselben Konversation. Im Hub unter Nachricht zitieren, um eine Antwort zuzuordnen erfahren Sie, wie die Auflösung funktioniert und was sie verfehlen kann.
Ein Listenmenü verwendet list.sections statt des gemeinsamen Button-Objekts; im Hub unter Buttons erfahren Sie, wie die anderen Typen stattdessen diese Struktur nutzen.
Sektionen und Zeilen
list.button_text ist das Label auf dem Button, der das Menü öffnet, maximal 20 Zeichen. Ein Tippen darauf öffnet das Menü: Jede Sektion wird unter ihrem eigenen title dargestellt, und jede Zeile innerhalb einer Sektion zeigt ihr text-Label mit dem optionalen description darunter in kleinerer Schrift. Der title einer Sektion ist auch dann erforderlich, wenn das Menü nur eine Sektion hat, weil WhatsApp ihn unabhängig davon über den Zeilen dieser Sektion anzeigt.
Der slug einer Zeile ist Ihr eigener Bezeichner für diese Zeile und wird dem Empfänger nie angezeigt. Nur text wird im Chat dargestellt, und der slug wird in der Antwort wortgenau zurückgegeben – derselbe Roundtrip, den der Hub für Buttons beschreibt. Die Zeichen in slug werden nicht validiert: Tragen Sie dort ein, was Ihr eigenes Routing benötigt.
Limits
| Feld | Grenze |
|---|---|
| Sektionen pro Nachricht | 1 bis 10 |
| Zeilen pro Sektion | 1 bis 10 |
| Zeilen über alle Sektionen | 10, insgesamt |
Sektions-title | erforderlich, 1 bis 24 Zeichen |
Zeilen-slug | erforderlich, 1 bis 200 Zeichen, beliebige Zeichen |
Zeilen-text (Label) | erforderlich, 1 bis 24 Zeichen, eindeutig über die gesamte Nachricht |
Zeilen-description | optional, bis zu 72 Zeichen |
list.button_text | erforderlich, 1 bis 20 Zeichen |
body_text | erforderlich, 1 bis 4096 Zeichen |
footer_text | optional, bis zu 60 Zeichen |
header.text | 1 bis 60 Zeichen |
Zwei dieser Grenzen werden leicht falsch gelesen.
Das Zeilenlimit ist zehn über alle Sektionen, nicht zehn pro Sektion. Jede Sektion erlaubt einzeln bis zu 10 Zeilen, aber die Nachricht insgesamt ist auf 10 Zeilen begrenzt. Drei Sektionen mit je 4 Zeilen bestehen jede Sektionsprüfung und überschreiten trotzdem das Gesamtlimit, das unabhängig vom Sektionslimit geprüft wird und E15055 mit einer Meldung zurückgibt, die die tatsächlich enthaltene Zeilenanzahl benennt.
body_text ist der einzige Typ, der die vollen 4096 Zeichen behält. Jeder andere interaktive Typ beschränkt seinen Body auf 1024; ein Listenmenü ist der einzige, den WhatsApp mit der vollen Länge zulässt. Nutzen Sie es, wenn die Auswahl mehr Kontext braucht als ein kurzer Prompt.
Auswahl auslesen
Ein Zeilentipp kommt als eigene eingehende Nachricht an, mit interactive_reply:
{
"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"
}Der slug, den Sie auf der gewählten Zeile gesetzt haben, wird wortgenau zurückgegeben, sodass Sie direkt darauf verzweigen können. description ist nur vorhanden, wenn die Zeile einen enthielt. Diese Antwort sehen Sie über die Nachrichtenliste oder GET /v1/whatsapp/messages/{id}; im Hub unter Antwort auslesen finden Sie den vollständigen Ablauf.
Limits und Sonderfälle
- Das Kundenservice-Fenster muss offen sein. Ein Listenmenü ist eine Service-Nachricht und kann nur innerhalb eines offenen Fensters zugestellt werden; siehe im Hub unter Kundenservice-Fenster. Die Fensterprüfung schlägt offen fehl, sodass ein
202kein Beweis dafür ist, dass das Fenster beim Versand tatsächlich offen war. frommuss eine Nummer sein, die Ihr Workspace besitzt. Wird sie weggelassen oder eine Nummer angegeben, die kein verbundener Sender ist, wird der Vorgang abgelehnt, bevor der Versand erstellt wird.- Der Header ist nur Text, und ein Media-Header schlägt als generischer Fehler fehl. Ein Listenmenü ist der einzige interaktive Typ, dessen Header kein Bild, Video oder Dokument enthalten kann. Wird trotzdem eines gesendet, kommt kein WhatsApp-spezifischer Fehlercode zurück: Es schlägt bei der allgemeinen Request-Validierung fehl, sodass ein Entwickler, der nach Fehlercode sucht, nur sieht, dass die Validierung fehlgeschlagen ist, und die Details lesen muss, um den Header als Ursache zu finden.
- Das sektionsübergreifende Zeilenlimit ist die Falle. Sektionslimits und das nachrichtenweite Gesamtlimit liegen beide bei 10, sodass sie wie dieselbe Zahl zweimal wirken. Sie sind nicht additiv: Ein Menü, das jede Sektionsprüfung besteht, kann trotzdem das Gesamtlimit überschreiten, und nur das Gesamtlimit wird durchgesetzt.
- Zeilen-Labels müssen über die gesamte Nachricht eindeutig sein, nicht nur innerhalb einer Sektion. Zwei Zeilen mit demselben
text-Label, auch in verschiedenen Sektionen, werden mit E15056 abgelehnt. Das ist eine eigene Regel von Bird, die Meta nicht explizit nennt: Die Antwort gibt das angetippte Label zurück, sodass ein Duplikat die Zuordnung mehrdeutig machen würde, und unterschiedlicheslug-Werte darunter helfen nicht, das aufzulösen. - Eine Meta-seitige Ablehnung jenseits der eigenen Prüfungen von Bird ist vage und kann verspätet eintreffen. Die Zeilenanzahl- und Duplikat-Label-Prüfungen von Bird fangen die zwei häufigsten Fehler ab, bevor etwas erstellt wird. Alles, was Meta darüber hinaus ablehnt, erscheint nach dem
202imlast_errorder Nachricht, nicht beim Send-Aufruf selbst.
Ein Zitat, das sich nicht auflösen lässt, lässt den Request fehlschlagen, bevor etwas erstellt oder berechnet wird: 404 E15071, wenn die ID keine Nachricht benennt, die dieser Workspace besitzt, 422 E15072, wenn sie eine benennt, die nicht zitiert werden kann. Für die Fehler, die jeder WhatsApp-Versand auslösen kann – ein geschlossenes Fenster, ein fehlender oder ungültiger Sender oder ein ungültiger Empfänger – siehe im Hub unter Fehler und WhatsApp-Nachrichten senden.
Nächste Schritte
- Interaktive WhatsApp-Nachrichten: was alle sechs interaktiven Typen gemeinsam haben
- Antwort-Buttons: für drei oder weniger Auswahlmöglichkeiten
- WhatsApp-Nachrichten senden: der Request-Envelope, das
202-Modell und sicheres erneutes Versuchen
Verwandte Ressourcen
Weiter mit der Dokumentation, Anleitungen und Beispielen zu diesem Thema.