Messaging

Media

Upload a file to send in a message, and get short-lived links to files.

Live

Files never pass through your API request body. You ask Gauge for an upload URL, upload the file straight to storage, then send a message that refers to it.

Ask for an upload URL

POST /v2/media · scope media:write · requires Idempotency-Key · live, unpinned key

{ "contentType": "application/pdf", "sizeBytes": 183402, "filename": "invoice-1042.pdf", "connectionId": "9b2f6c1e-3d4a-4e5b-8f70-1a2b3c4d5e6f" }
Field
contentTypeOne of image/jpeg, image/png, image/webp, image/gif, video/mp4, video/3gpp, audio/ogg, audio/opus, audio/webm, audio/mpeg, audio/mp4, audio/aac, audio/amr, application/pdf. Anything else answers 400.
sizeBytesThe exact size. It is signed into the upload URL: storage refuses a body of any other length.
filenameOptional, up to 200 characters.
connectionIdOptional but recommended: the file is checked against that connection's limits now rather than at send time.

201 answers the media with a presigned upload:

{
  "id": "5d1c7e2a-9b3f-4a6d-8e0c-2f4a6b8d0e1f",
  "contentType": "application/pdf",
  "sizeBytes": 183402,
  "filename": "invoice-1042.pdf",
  "status": "pending",
  "createdAt": "2026-10-21T09:30:00.000Z",
  "expiresAt": "2026-10-21T09:45:00.000Z",
  "upload": {
    "url": "https://…",
    "method": "PUT",
    "headers": { "Content-Type": "application/pdf", "Content-Length": "183402" },
    "expiresAt": "2026-10-21T09:45:00.000Z"
  },
  "download": null
}

Upload the file

PUT the bytes to upload.url with exactly upload.headers, within 15 minutes. The URL is valid for that one file only.

curl -X PUT "$UPLOAD_URL" -H "Content-Type: application/pdf" -H "Content-Length: 183402" --data-binary @invoice-1042.pdf

Send it

Use the media id as mediaId in POST /v2/messages, on a connection whose capabilities.sendMedia is true. text becomes the caption. A send before the upload landed answers 400 with reason media_not_uploaded.

Limits

Largest file
Any upload (no connectionId)16 MB
WhatsApp Cloud and WhatsApp Web16 MB; photos on WhatsApp Cloud 5 MB
Every other channel that sends files7 MB

Over the limit answers 413 payload_too_large with reason file_too_large and details.maxBytes. A connection that cannot send files answers 422 unsupported_channel_action with reason media_not_supported. Each connection states its own limit as limits.maxMediaBytes on GET /v2/connections/{id}.

Download a file you uploaded

GET /v2/media/{id} · scope media:read

Once the file has landed, status is uploaded and download is a signed link valid for 5 minutes. Fetch the file when you need it rather than storing the link. Until then download is null. A key sees the files its member uploaded, or every file when its member sees every conversation.

Files on messages (what a customer sent you, or any file on a message) are downloaded through the message: GET /v2/messages/{id}/attachments/{index}. That is the link a webhook's media[].url carries.

When file storage is not available

File uploads and downloads need storage the internet can reach. Where a deployment has none configured yet, POST /v2/media, GET /v2/media/{id} and GET /v2/messages/{id}/attachments/{index} answer 503 with code media_unavailable. It is a state of the deployment, not of your request: text, template and interactive sends are unaffected. Retry later.

Which channels carry files today: Channels.

On this page