Skip to main content
Images, videos, documents, voice notes and stickers all work the same way: you give us a public link and we fetch the file from it.
There is no upload endpoint. You cannot post a file to this API. If your file is not already on the internet somewhere, put it there first.
That is a deliberate scope decision, not an oversight. Hosting uploads would mean storage, quotas, retention rules and virus scanning, none of which exist here yet. A link works when opening it in a private browser window downloads the file itself with no login and no intermediate page.

Works

A direct link to the bytes. Signed URLs are fine as long as they are still valid at the moment you call the API.

Fails

Preview pages, share pages and video sites serve HTML, not a file. Private addresses are refused outright.

The rules, exactly

Every refusal gives the same message — Field "url" must be a publicly reachable http(s) URL to the file. — regardless of which rule was broken. That is on purpose: it is actionable either way, and a per-reason message would let someone map a private network from outside by watching which hosts produce which wording.

The two failures, and how to tell them apart

The URL failed a check before anything was fetched: wrong scheme, malformed, too long, credentials in it, or a private address.Fix the URL. Retrying the same one will never work. details.field names the field — url, or buttons[N].url for a link button.
The URL looked fine but the file could not be downloaded: a 404, an expired signed link, a hostname that does not resolve, a TLS failure, or a page where a file was expected.Open the link in a private browser window. If it does not download the raw file for you, it will not for us either.

Which endpoint for which file

Always set filename on a document. It is the name the recipient sees and saves. Without it the name comes from the URL, which is often something like download.php or a signed-URL blob.

Formats

We do not restrict file types — WhatsApp decides what it can render. In practice:
  • Images — JPEG and PNG are safest.
  • Video — MP4 with H.264 video and AAC audio.
  • Audio — MP3 and OGG/Opus arrive as playable voice notes.
  • Stickers — WebP. Other formats may arrive as an ordinary image or not render at all.
  • Documents — anything. PDF is the most predictable across devices.
mime_type is an optional hint you can send with image, video and document. It is checked for the shape type/subtype only — we never verify it matches the actual file, so a wrong hint is worse than none.

Sizes

There is no size limit in this API, but there are two real ones underneath:
  • WhatsApp’s own attachment limits. A file that is too big for WhatsApp will fail however it was sent.
  • Time. The file has to be fetched during your request. A large file over a slow link can exhaust the request budget and come back as 502 upstream_unavailable.
Keep media small. A 200 KB receipt sends instantly; a 40 MB video is a gamble. The file is fetched during your API call, not later. So:
  • A signed URL must still be valid at the moment you send. Generate it right before the call, not the night before.
  • Do not delete the file immediately after the API returns 200. The fetch has already happened by then, but keeping it around a while makes debugging far easier.
  • If your storage is private by default, generate a short-lived public link for the send.