Send Media with the WhatsApp API: Images, PDFs, Video
Text gets a reply. A photo of the actual product, the invoice as a PDF, or a 20-second video of how to fix the thing gets the problem solved. That's why most WhatsApp integrations need media within a week of launch, and why "the image didn't arrive" and "the video won't play on Android" are such common tickets.
To send media with the WhatsApp API, you need to know three things: which file types and sizes Meta accepts, whether to upload the file or hand Meta a link, and the encoding rules that decide whether a voice note or video plays properly on the customer's phone.
This guide covers all three for Meta's Cloud API, with limits taken from Meta's media documentation as of October 2026, then how media works on Tenashi's API. For everything else about the platform, see our complete guide to the WhatsApp API.
Supported types and size limits
Meta's media page lists these supported formats as of October 2026:
| Media | Formats (MIME type) | Max size | Notes |
|---|---|---|---|
| Image | JPEG (image/jpeg), PNG (image/png) | 5 MB | Must be 8-bit RGB or RGBA |
| Video | MP4 (video/mp4), 3GPP (video/3gpp) | 16 MB | H.264 video, AAC audio, one audio stream or none |
| Audio | AAC, AMR, MP3 (audio/mpeg), M4A (audio/mp4), OGG (audio/ogg, Opus only) | 16 MB | OGG must be Opus and mono |
| Document | PDF, TXT, DOC, DOCX, XLS, XLSX, PPT, PPTX | 100 MB | Other types may send but aren't supported |
| Sticker | WebP (image/webp) | 100 KB static, 500 KB animated | WebP is only for sticker messages |
Captions on images, videos and documents can be up to 1,024 characters. Meta's audio and sticker message formats have no caption field.
Two consequences people miss. WebP and GIF aren't on the image list, so convert them to JPEG or PNG before sending as an image. And HEIC photos from iPhones aren't supported either, so convert anything a user uploads to your system before forwarding it on WhatsApp.
Upload the file or send a link?
Every media message takes either an id (a file you uploaded to Meta) or a link (a public URL Meta fetches). Meta's message references mark link as "not recommended" and suggest uploaded media for better performance.
Upload, then send by id | Send by link | |
|---|---|---|
| How | POST /PHONE_NUMBER_ID/media, get an ID | Put a public HTTPS URL in the message |
| Reuse | The ID works for 30 days, for anyone you message from that number | Meta caches the fetched file for 10 minutes per URL |
| Speed at volume | Best; Meta recommends it for high throughput | Depends on your server |
| Privacy | File never needs a public URL | URL must be reachable by Meta, so effectively public |
| Updating a file | Upload again for a new ID | Cached copy is reused for 10 minutes; add a query string to force a fresh fetch |
The caching detail bites people who regenerate a file at the same URL, such as invoice.pdf rebuilt with a correction. If you send the same link again within 10 minutes, Meta reuses the old cached file. Meta's documented fix is to append a random query string, for example invoice.pdf?v=2.
For a single customer-specific file, either works. For anything sent to many people, such as a product brochure for a campaign, upload once and reuse the ID.
Upload a file and send it
Upload with a multipart request. The type comes from the MIME type you attach to the file field:
curl "https://graph.facebook.com/v23.0/PHONE_NUMBER_ID/media" \
-H "Authorization: Bearer $WHATSAPP_TOKEN" \
-F "messaging_product=whatsapp" \
-F "file=@./INV-1042.pdf;type=application/pdf"
The response is just an ID:
{ "id": "1037543291543636" }
Send it as a document. filename is what the customer sees and decides the file icon, so include the extension:
curl "https://graph.facebook.com/v23.0/PHONE_NUMBER_ID/messages" \
-H "Authorization: Bearer $WHATSAPP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "+919811122233",
"type": "document",
"document": {
"id": "1037543291543636",
"filename": "INV-1042.pdf",
"caption": "Your invoice for October. Reply here with any questions."
}
}'
An image by link looks the same with a different type:
{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "+919811122233",
"type": "image",
"image": {
"link": "https://example.com/products/blue-kettle.jpg",
"caption": "The blue one, back in stock today."
}
}
These free-form media messages need an open 24-hour customer service window. Outside it, media has to travel inside an approved template with a media header; our guide to sending messages by API covers the template side. Examples use Graph API v23.0; use the current version from Meta's changelog.
Uploaded files can be deleted early with DELETE /MEDIA_ID, which is worth doing for sensitive documents once they're delivered.
Voice notes versus audio files
The same audio message type produces two different experiences, and the difference is one flag and one codec:
- A voice note shows your business profile picture, a microphone icon, and can be transcribed on the user's phone. Send an OGG file encoded with Opus and set
"voice": true. Meta notes the play icon only appears if the file is 512 KB or smaller; larger files show a download arrow instead. - A basic audio message shows a music icon and a download button. Any supported audio format works, with
voiceleft out or false.
Converting a recording into a voice note that meets Meta's rules (Opus, mono):
ffmpeg -i recording.m4a -vn -c:a libopus -ac 1 -b:a 24k voice.ogg
At 24 kbps, a minute of speech comes in well under the 512 KB play-icon threshold. Since March 17, 2026, Meta also sends a played status webhook the first time a user plays a voice message.
Video that plays on every phone
Meta requires H.264 video and AAC audio, and adds a warning: Android WhatsApp clients don't support H.264 "High" profile videos with B-frames. Many phones and editing apps export exactly that, so a video can play fine on iPhone and fail on Android. Meta recommends Main profile without B-frames, or Baseline, with the moov atom placed before the media data.
This ffmpeg command applies all of that, keeps at most one audio stream, and works whether or not the source has sound:
ffmpeg -i input.mov -map 0:v:0 -map "0:a:0?" \
-c:v libx264 -profile:v main -bf 0 -pix_fmt yuv420p \
-c:a aac -movflags +faststart output.mp4
We checked the output with ffprobe: H.264 Main profile, zero B-frames, AAC audio. Keep the result under 16 MB, which in practice means short clips or a lower resolution; add -vf scale=-2:720 to cap the height at 720 pixels.
Media errors you'll meet
131053: media upload failed. Most often a MIME type that doesn't match the file, such as a PNG named.jpgor uploaded withtype=image/jpeg. Meta suggests checking withfile -I yourfileand making the extension match.- Expired or invalid media ID. Upload IDs last 30 days. A send with an expired ID fails with an error instead of a message ID, so re-upload rather than caching IDs forever.
131051: unsupported message type. Thetypeyou sent isn't one Cloud API supports for this message; check it against Meta's list of message types.131052on inbound media. Customers can send files up to 100 MB; bigger ones arrive as this error. Downloading what customers send is covered in receiving WhatsApp messages by API.
The full list, with fixes, is in our WhatsApp API error codes reference.
Sending media through Tenashi
Tenashi's API attaches media to the same POST /api/v1/messages call as text. Pass media as a URL Tenashi downloads, or as base64 with a mimetype, add filename for documents, and the text becomes the caption:
curl https://usetenashi.com/api/v1/messages \
-H "Authorization: Bearer $TENASHI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice-INV-1042" \
-d '{
"to": "+919811122233",
"text": "Your invoice for October",
"media": { "url": "https://example.com/invoices/INV-1042.pdf", "filename": "INV-1042.pdf" }
}'
Tenashi's limits are its own and differ from Meta's: images up to 5 MB, video up to 16 MB, and PDFs and Office files up to 25 MB. A file over the limit returns media_too_large. Because it's not the Cloud API, there's no template or 24-hour window, and you can send the same file into a WhatsApp group by using conversationId instead of to.
Where Tenashi fits
If the files you send are invoices, quotes, photos and voice replies inside ongoing customer conversations, Tenashi sends them from the number your team already uses, linked by QR scan, and every file lands in the shared inbox thread where a teammate can follow up. No template approvals, no per-message fees; plans start from $18/mo with the API included.
The limit to know: sends are paced, one message every 4 to 12 seconds per number, so Tenashi isn't the tool for mailing a brochure to thousands of people at once.
Read the API docs · Get started
FAQ
What is the maximum file size for media on the WhatsApp Cloud API?
As of October 2026, Meta allows images up to 5 MB, video and audio up to 16 MB, documents up to 100 MB, and stickers up to 100 KB static or 500 KB animated. Images must be JPEG or PNG, and videos MP4 or 3GPP with H.264 video and AAC audio.
Should I send WhatsApp media by link or by uploaded ID?
Meta recommends uploading and sending by ID for better performance. An uploaded ID can be reused for 30 days for anyone you message from that number, and the file never needs a public URL. Links work too, but Meta caches each URL's file for 10 minutes, so add a query string when a file changes.
Why won't my WhatsApp video play on Android?
Android WhatsApp clients don't support H.264 High profile video with B-frames, which many phones and editors export by default. Re-encode to H.264 Main or Baseline profile without B-frames, with AAC audio, a single audio stream and the moov atom first, using ffmpeg's faststart flag.
How do I send a voice note with the WhatsApp API?
Send an audio message with the voice flag set to true, using an OGG file encoded with the Opus codec in mono. The voice note shows your profile picture and can be transcribed on the user's phone. Keep it at 512 KB or smaller, or WhatsApp shows a download icon instead of play.
Can I add a caption to a WhatsApp document message?
Yes. Image, video and document messages accept a caption of up to 1,024 characters on the Cloud API. Documents also accept a filename, which the customer sees and which sets the file icon, so include the extension. Audio and sticker messages have no caption field.
Getting media right is mostly about formats and a couple of encoding flags. To attach invoices and photos to the chats your team is already in, read how media works in Tenashi's API.