SigFollow
Sign in

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/media

Scope: messages:send

Request

The body must be multipart/form-data with two fields:

NameTypeRequiredDescription
messaging_productstringyesAlways "whatsapp".
filebinaryyesThe 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 legacy application/vnd.ms-excel
Legacy .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 (declared Content-Typedoesn't match the file's first bytes)
  • 413 — file exceeds the SigFollow 16 MiB cap
  • 401 / 403 — auth / scope failures (see authentication)