Inbound media
The easy path — it’s on the webhook
Section titled “The easy path — it’s on the webhook”Every inbound media message arrives on your message.received webhook
with a media_url already signed and ready to download (valid ~1 hour), plus
its mime type and original filename:
{ "event": "message.received", "data": { "conversation_id": "c9e6f0f7-...", "phone": "919876543210", "phone_number_id": "1066...", "display_phone_number": "917810083015", "message": { "id": "wamid...", "type": "image", "text": "here's my materials list", "media_url": "https://blr1.digitaloceanspaces.com/…?X-Amz-Signature=…", "media_mime_type": "image/jpeg", "media_filename": "list.jpg", "timestamp": "2026-07-16T09:10:00+00:00" } }}GET the media_url as-is — no auth header, no extra call. type is
image · document · audio · video · sticker for media messages (text
messages carry no media_url).
On demand — the media endpoint
Section titled “On demand — the media endpoint”Fetch a fresh signed URL any time, authenticated with your API key. Pass
either a message_id or the stored path:
| Field | Type | Required | Description |
|---|---|---|---|
| message_id | string | One of the two | Whatbot’s message id, from List Messages. Not the webhook’s message.id — that is WhatsApp’s wamid, which this endpoint cannot look up (the request fails instead of returning a link). |
| path | string | One of the two | A stored media path in your workspace, whatsapp-media/inbound/<your workspace id>/…. |
curl "https://api.whatbot.in/public/v1/media?message_id=8f1c..." \ -H "X-API-Key: wa_live_xxx"curl "https://api.whatbot.in/public/v1/media?path=whatsapp-media/inbound/<org>/<file>.jpg" \ -H "X-API-Key: wa_live_xxx"{ "media_url": "https://blr1.digitaloceanspaces.com/…?X-Amz-Signature=…", "media_mime_type": "image/jpeg", "media_filename": "list.jpg"}Then GET media_url to download the bytes.
| Status | Cause |
|---|---|
403 | The path is not under your workspace’s prefix |
404 | No message with that id in your workspace, or it has no media |
422 | Neither message_id nor path was given |
502 | The link couldn’t be generated — try again |
Listing messages already signs media
Section titled “Listing messages already signs media”GET /conversations/{id}/messages also returns media with media_url already
signed — so a message you read back is immediately downloadable, no separate
call needed:
curl https://api.whatbot.in/public/v1/conversations/{id}/messages \ -H "X-API-Key: wa_live_xxx"Each customer-sent media row’s media_url is a signed link (valid ~1 hour; audio ~1 day), alongside
media_mime_type. The original filename is not in the list response — fetch it from
GET /media?message_id=…, which returns media_filename.