Overview
Media objects are managed with dedicated Graph API endpoints:
- Upload:
POST /<PHONE_NUMBER_ID>/media - Retrieve metadata/URL:
GET /<MEDIA_ID> - Delete:
DELETE /<MEDIA_ID>
Media lifecycle:
- Upload file and receive
media_id. - Reuse
media_idin message payloads. - Retrieve temporary download URL when needed.
- Delete media when no longer needed.
Upload Media
Upload uses multipart/form-data:
curl -X POST "https://graph.facebook.com/<GRAPH_VERSION>/<PHONE_NUMBER_ID>/media" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-F "messaging_product=whatsapp" \
-F "file=@<LOCAL_FILE_PATH>;type=<MEDIA_MIME_TYPE>"
Response:
{
"id": "<MEDIA_ID>"
}
Retrieve Media Metadata
curl -X GET "https://graph.facebook.com/<GRAPH_VERSION>/<MEDIA_ID>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
Response:
{
"messaging_product": "whatsapp",
"url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=<MEDIA_ID>&ext=<EXPIRY>&hash=<HASH>",
"mime_type": "<MEDIA_MIME_TYPE>",
"sha256": "<MEDIA_SHA256>",
"file_size": 12345,
"id": "<MEDIA_ID>"
}
The returned URL is temporary and short-lived. Download immediately rather than storing the URL for later reuse.
Download Media Binary
After retrieving the temporary URL, perform an authenticated GET:
curl -L -X GET "<TEMP_MEDIA_URL>" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
--output "<OUTPUT_FILENAME>"
Delete Media
curl -X DELETE "https://graph.facebook.com/<GRAPH_VERSION>/<MEDIA_ID>" \
-H "Authorization: Bearer <ACCESS_TOKEN>"
Response:
{
"success": true
}
Security and Compliance
- Treat media URLs and access tokens as sensitive data.
- Do not log full bearer tokens.
- Restrict media retention according to your compliance policy.
- Verify file type and scan uploaded files before downstream processing.
- Use queue-based media processing for spikes.
- Retry transient upload/download failures with backoff.
- Add idempotent job keys so repeated webhook events do not duplicate downloads.