kenari.dev

Media#

kenari forwards Meta's media endpoints. You upload against a phone number, and you retrieve or delete by media id with the phone number given in the query string.

ActionRequest
UploadPOST /{version}/{phone_number_id}/media
Retrieve URL and metadataGET /{version}/{media_id}?phone_number_id={phone_number_id}
DeleteDELETE /{version}/{media_id}?phone_number_id={phone_number_id}

Upload#

Send the multipart form Meta expects. kenari forwards it to Meta without parsing or rewriting it (bodies up to 1 MiB are buffered first, larger ones are streamed), and your Content-Type header, multipart boundary included, is passed on exactly.

bash
curl -X POST "https://api.kenari.dev/v21.0/$PHONE_NUMBER_ID/media" \  -H "Authorization: Bearer $KENARI_API_KEY" \  -F "messaging_product=whatsapp" \  -F "type=image/jpeg" \  -F "file=@receipt.jpg"
json
{ "id": "<media id>" }

Use the returned id when you send a media message.

Uploads count against the number's per-second rate limit, the same bucket as sends.

Retrieve#

phone_number_id is required. It has to be a number connected to your account, and kenari uses it to decide which WABA's token the request is made with.

bash
curl "https://api.kenari.dev/v21.0/$MEDIA_ID?phone_number_id=$PHONE_NUMBER_ID" \  -H "Authorization: Bearer $KENARI_API_KEY"

Meta's JSON response, including the short-lived download url, is returned unchanged.

Delete#

bash
curl -X DELETE "https://api.kenari.dev/v21.0/$MEDIA_ID?phone_number_id=$PHONE_NUMBER_ID" \  -H "Authorization: Bearer $KENARI_API_KEY"

Retrieve and delete count against the WABA's 5,000 requests/hour bucket, not the number's per-second bucket.

Size limit#

kenari accepts request bodies of up to 100 MB (104,857,600 bytes).

  • If your Content-Length is over the limit, kenari returns 413 before reading the body.
  • If you send without Content-Length (chunked), kenari counts bytes as they stream and stops with a 413 as soon as the limit is passed.
json
{  "error": {    "message": "Request body exceeds 100 MB.",    "type": "KenariPayloadTooLargeException",    "code": 1004,    "fbtrace_id": "req_…"  }}

This is kenari's limit on the whole request. Meta has its own, smaller per-type limits for media (images, video, audio, documents, stickers). A file under 100 MB can still be rejected by Meta, and you'll get Meta's error unchanged. See Meta's supported media types.

Timeouts#

kenari waits up to 120 seconds for Meta to answer a media request (upload, retrieve or delete). After that it returns 503 KenariUpstreamException with Meta request timed out. Uploads are never retried for you.