WhatsApp-berichten ontvangen
Inkomende berichten landen op dezelfde resource als uitgaande, zonder apart inbox-endpoint om te pollen. Lees ze via de berichtenlijst in het dashboard, of via de API met GET /v1/whatsapp/messages/{id} nadat je de lijst hebt gefilterd op inkomend.
Elk inkomend bericht verlengt het klantenservicevenster tot 24 uur na de eigen timestamp van dat bericht, en dat is wat een vrij antwoord van jouw kant bezorgbaar maakt. Een bericht dat Bird laat bereikt, draagt daarom het venster dat het contact daadwerkelijk heeft verleend, en een latere deadline die al geregistreerd staat wordt nooit verkort.
Wat een inkomend bericht bevat
Elk inkomend bericht deelt één envelope: een id, direction: "inbound", het contact in from, je eigen nummer in to, een status van received, en een created_at. Precies één contentveld staat ernaast en geeft aan wat het contact heeft gestuurd:
Codevoorbeeld
{
"id": "wam_01kya19eknftrs2s6p82asmvnh",
"direction": "inbound",
"from": { "phone_number": "+14155550100" },
"to": { "phone_number": "+13124495569" },
"status": "received",
"text": { "body": "Is my order out for delivery yet?" },
"created_at": "2026-08-25T09:04:11Z"
}from benoemt het contact op basis van de identiteit die WhatsApp rapporteert: een E.164-phone_number, een bsuid, of beide, plus de username en display_name die ze publiceren. Een contact dat een WhatsApp-gebruikersnaam heeft aangenomen, kan je bereiken zonder telefoonnummer; zie business-scoped user-ID's voor wat je opslaat en hoe je om een nummer vraagt.
Eén van deze contentvelden, een arm, bevat wat ze hebben gestuurd, en precies één arm is ingesteld op elk bericht. Elk heeft een eigen pagina, met de leesstructuur, de whatsapp.received-payload en waar je op moet letten:
| Veld | Wat een inkomend bericht bevat |
|---|---|
| text | body, het bericht dat het contact heeft getypt |
| image | Een id, url, mime_type, en eventuele caption |
| video | Dezelfde mediavelden, plus eventuele caption |
| audio | Dezelfde mediavelden, plus voice bij een voicenote; er is geen bijschrift |
| sticker | Dezelfde mediavelden, plus animated |
| document | Dezelfde mediavelden, plus eventuele filename en caption |
| location | latitude en longitude, en soms name, address, of een url |
| contact_cards | Een of meer contactkaarten die het contact heeft gedeeld |
| interactive_reply | De slug en text van de knop of rij waarop het contact heeft getikt |
| unsupported | Het WhatsApp-contenttype dat de API niet modelleert, zoals een bestelling |
Twee tikken komen binnen op een arm die je misschien niet verwacht. Een locatieverzoek beantwoordt als een gewoon inkomend location, en een contactinfoverzoek beantwoordt als contact_cards, dus een integratie die alleen interactive_reply bewaakt voor een tik mist ze allebei.
Inkomende media ophalen
Een inkomende image, video, audio, sticker of document komt binnen als een verwijzing naar een bestand dat Bird heeft opgeslagen, niet als het bestand zelf:
Codevoorbeeld
{
"image": {
"id": "waf_01kyb2m4xq7whs0d8n3prv6tez",
"url": "https://platform.bird.com/v1/whatsapp/messages/wam_01kya19eknftrs2s6p82asmvnh/media/waf_01kyb2m4xq7whs0d8n3prv6tez",
"mime_type": "image/jpeg",
"caption": "Is this the right part?"
}
}Haal de bytes op met de mediamethode van het kanaal, waarbij je de message-id en de media-id meegeeft:
const media = await bird.whatsapp.messages.media(
"wam_01kya19eknftrs2s6p82asmvnh",
"waf_01kyb2m4xq7whs0d8n3prv6tez",
);
console.log(media.contentType, media.contentLength);media = client.whatsapp.messages.media(
"wam_01kya19eknftrs2s6p82asmvnh", "waf_01kyb2m4xq7whs0d8n3prv6tez"
)
print(media.content_type, media.content_length)media, err := client.Whatsapp.Messages.Media(context.Background(),
"wam_01kya19eknftrs2s6p82asmvnh", "waf_01kyb2m4xq7whs0d8n3prv6tez")
if err != nil {
log.Fatal(err)
}
fmt.Println(media.ContentType, media.ContentLength)$media = $bird->whatsapp->messages->media('wam_01kya19eknftrs2s6p82asmvnh', 'waf_01kyb2m4xq7whs0d8n3prv6tez');
file_put_contents('photo.jpg', $media->data);
echo $media->contentType, ' ', $media->contentLength;bird whatsapp media <message-id> <media-id>curl -L -X GET "https://{region}.platform.bird.com/v1/whatsapp/messages/{message_id}/media/{media_id}" \
-H "Authorization: Bearer $TOKEN"Je krijgt de bytes terug met het mime_type-opslagtype dat ervoor is gedeclareerd. Een id die Bird niet herkent retourneert 404, en een uitgaand bericht heeft geen opgeslagen media om te serveren.
Een bericht is 30 dagen na ontvangst terug te lezen, en de media overleeft het bericht nooit. Dit endpoint leest het bericht voordat het het bestand serveert, dus zodra dat venster verstreken is antwoorden beide met 404. Sla elk bestand dat je langer nodig hebt op zolang het bericht nog leesbaar is. Het enige geval dat eerder eindigt is wanneer de opgeslagen bytes verdwijnen voordat het venster voorbij is: de fetch antwoordt met 410 E15021, en het bericht is nog steeds terug te lezen met de mime_type en caption van de media.
Onder de motorkap antwoordt dit endpoint met 302 met een presigned URL die 15 minuten geldig is. De SDK's en de CLI nemen die stap voor je. Als je het direct aanroept, draagt de presigned URL zijn eigen credential, dus het doorgestuurde request mag niet ook je Authorization-header meesturen. Beide meesturen mislukt. curl -L laat de header bij een cross-host redirect vanzelf vallen; een client die headers letterlijk doorstuurt moet de Location als een apart, niet-geauthenticeerd request ophalen.
Geciteerde antwoorden
in_reply_to_message_id benoemt het bericht dat een inkomend bericht beantwoordt, wanneer WhatsApp het als antwoord markeert:
Codevoorbeeld
{
"id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"direction": "inbound",
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"text": { "body": "Yes, that one" }
}WhatsApp markeert niet elk antwoord, en een ongemarkeerd antwoord bevat helemaal geen ID. Het veld wordt ook weggelaten wanneer het geciteerde bericht niet kan worden gekoppeld aan een bericht dat Bird bewaart: een bericht dat is verstuurd voordat deze werkruimte ze begon op te slaan, of een bericht dat ouder is dan de 15 dagen die Bird de eigen bericht-ID's van WhatsApp bewaart. Een misser laat het veld weg in plaats van er een te rapporteren, wat hetzelfde leest als een antwoord dat niets beantwoordt.
Behandel het veld als hint, niet als sleutel. metadata op je eigen verzending helpt hier niet, omdat het op jouw bericht blijft staan en nooit meereist naar het antwoord van het contact. Een integratie die moet weten bij welke vraag een antwoord hoort, houdt dus zelf bij welke vraag ze het laatst aan dat contact heeft gesteld. Zie Een bericht citeren voor de uitgaande kant.
De webhook
Abonneer je op whatsapp.received om op een inkomend bericht te reageren zodra het binnenkomt, in plaats van de lijst te pollen. De payload bevat de content bovenop de event-envelope, dus een endpoint hoeft niet apart op te vragen:
Codevoorbeeld
{
"type": "whatsapp.received",
"timestamp": "2026-08-25T09:04:11.118Z",
"data": {
"whatsapp_id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
"direction": "inbound",
"from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
"to": { "phone_number": "+13124495569" },
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"interactive_reply": {
"type": "button",
"button": { "slug": "cancel-booking", "text": "Cancel" }
},
"tags": null,
"metadata": null
}
}Zie WhatsApp-events voor de volledige envelope en de rest van de eventlijst.
Volgende stappen
- Serviceberichten: de verzendkant van dezelfde content-arms
- WhatsApp-berichten versturen: antwoorden binnen het servicevenster en een bericht citeren
- WhatsApp-events: de volledige eventlijst, via de API of webhooks
- WhatsApp-log: het gesprek bekijken in het dashboard
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.
Bekijk de gidsConnecting WhatsApp to Bird: from buying a number to a live channelBegrijp het conceptWhat is the 24-hour customer service window on WhatsApp?Gebruik de toolWhatsApp message builderOntdek de mogelijkheidWhatsApp
Probeer de oefening en ontvang een implementatieoverzicht