Sign inGet started

Receiving WhatsApp video

A clip a contact records or attaches arrives as an inbound message carrying video: the same media reference every inbound media arm uses, plus any caption they typed under it.

What an inbound video carries

Ejemplo de código
{
  "id": "wam_01kyc5r9pewu7s3j6m0xyd5qgb",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "video": {
    "id": "waf_01kyc4n5yr8xit1e9o4qsw7ufa",
    "url": "https://platform.bird.com/v1/whatsapp/messages/wam_01kyc5r9pewu7s3j6m0xyd5qgb/media/waf_01kyc4n5yr8xit1e9o4qsw7ufa",
    "mime_type": "video/mp4",
    "caption": "The rattle starts around 0:12"
  },
  "created_at": "2026-08-25T09:11:48Z"
}
FieldWhat it carries
idThe stored file, to pass as media_id when fetching the bytes
urlA Bird URL, fetched with your API key
mime_typeThe media type WhatsApp reported for the clip, such as video/mp4
captionThe text the contact typed under the video; absent when they sent none
The arm carries no duration, no dimensions, and no thumbnail. Read those from the file itself once you have the bytes, or from your own media pipeline.
id and mime_type appear only on an inbound video, since Bird learns both by fetching the file. An outbound video reads back with the url you supplied and no id.

Fetching the bytes

Pass the message ID and the media id to the channel's media method. The hub's fetching inbound media carries that call in every language, along with the redirect and header rules it follows.
A video is the largest thing a contact is likely to send you, and the fetch serves the bytes straight from storage rather than through the API, so stream the response to disk or to your own bucket rather than buffering it. The message and its media expire together, 30 days after the message arrives; the hub's fetching inbound media owns that window and what the reads return once it passes.

The webhook payload

whatsapp.received carries the video arm on the event envelope:
Ejemplo de código
{
  "type": "whatsapp.received",
  "timestamp": "2026-08-25T09:11:48.204Z",
  "data": {
    "whatsapp_id": "wam_01kyc5r9pewu7s3j6m0xyd5qgb",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
    "direction": "inbound",
    "from": { "phone_number": "+14155550100" },
    "to": { "phone_number": "+13124495569" },
    "video": {
      "id": "waf_01kyc4n5yr8xit1e9o4qsw7ufa",
      "url": "https://platform.bird.com/v1/whatsapp/messages/wam_01kyc5r9pewu7s3j6m0xyd5qgb/media/waf_01kyc4n5yr8xit1e9o4qsw7ufa",
      "mime_type": "video/mp4",
      "caption": "The rattle starts around 0:12"
    },
    "tags": null,
    "metadata": null
  }
}
Fetch the clip from a queued worker rather than inside the webhook handler: the endpoint has to answer quickly, and the media stays available for the whole retention window.

Things to watch

  • A video note reads as a video. WhatsApp's round video note arrives on this arm with no flag distinguishing it, unlike audio, where a voice note sets voice.
  • One clip per message. Several videos arrive as several inbound messages, each with its own media reference.

Next steps