API reference
Media
Upload binary media to Meta and reuse the resulting media_id across multiple message sends — cheaper than re-uploading and required for some message types.
Upload media
POST
/v1/:phoneNumberId/mediaScope: messages:send
Request
The body must be multipart/form-data with two fields:
| Name | Type | Required | Description |
|---|---|---|---|
| messaging_product | string | yes | Always "whatsapp". |
| file | binary | yes | The media file. MIME type must match the file's magic bytes — SigFollow inspects the first bytes of the upload and rejects mismatches with 400. This blocks HTML payloads disguised as images. |
MIME whitelist enforced
Only the explicit Meta-supported MIME types are accepted. Generic types like
application/octet-stream are rejected. Current whitelist:- Image:
image/jpeg,image/png - Sticker:
image/webp - Video:
video/mp4,video/3gpp - Audio:
audio/aac,audio/mp4,audio/mpeg,audio/amr,audio/ogg - Document:
application/pdf,text/plain,.docx,.xlsx,.pptx, plus legacyapplication/vnd.ms-excel
.doc / .ppt are intentionally excluded — there is no magic-byte rule for them yet, so allowing the MIME would create a forgery hole.Size cap: 16MB
SigFollow caps every upload at 16 MiB(the stricter of Meta's per-type limits) regardless of the file type. Larger documents need to go through Meta's resumable upload flow — contact support if you have a real use case.
HMAC signing not enforced on /media
Unlike JSON endpoints, this multipart upload route does not check the
X-SigFollow-Signature header even when the API key has requireSignature on — NestJS cannot reliably recompute a body hash from a streamed multipart payload. API key auth and rate limiting still apply.Example
curl -X POST https://api.sigfollow.com/v1/PHONE_NUMBER_ID/media \
-H "Authorization: Bearer sflo_live_xxx" \
-F "messaging_product=whatsapp" \
-F "file=@/path/to/picture.jpg;type=image/jpeg"Response
{ "id": "1234567890" }Use id in a subsequent message send:
{
"messaging_product": "whatsapp",
"to": "{{Recipient-Phone-Number}}",
"type": "image",
"image": { "id": "1234567890", "caption": "Optional" }
}See the Messages reference for media-type message bodies.
Errors
400— MIME outside the whitelist or magic-byte mismatch (declaredContent-Typedoesn't match the file's first bytes)413— file exceeds the SigFollow 16 MiB cap401/403— auth / scope failures (see authentication)