Overview
Media objects are managed through dedicated, connection-scoped runtime 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://api.dualhook.com/v25.0/<PHONE_NUMBER_ID>/media" \
-H "Authorization: Bearer <DUALHOOK_API_KEY>" \
-F "messaging_product=whatsapp" \
-F "file=@<LOCAL_FILE_PATH>;type=<MEDIA_MIME_TYPE>"
Response:
{
"id": "<MEDIA_ID>"
}
Retrieve Media Metadata
curl -X GET "https://api.dualhook.com/v25.0/<MEDIA_ID>" \
-H "Authorization: Bearer <DUALHOOK_API_KEY>"
Response:
{
"messaging_product": "whatsapp",
"url": "https://api.dualhook.com/v25.0/<MEDIA_ID>/content",
"mime_type": "<MEDIA_MIME_TYPE>",
"sha256": "<MEDIA_SHA256>",
"file_size": 12345,
"id": "<MEDIA_ID>"
}
The returned URL is a stable, authenticated Dualhook content route. It obtains Meta's short-lived URL only when requested and never exposes that Meta URL to your application.
Download Media Binary
Download through the authenticated content route:
curl -X GET "https://api.dualhook.com/v25.0/<MEDIA_ID>/content" \
-H "Authorization: Bearer <DUALHOOK_API_KEY>" \
--output "<OUTPUT_FILENAME>"
Delete Media
curl -X DELETE "https://api.dualhook.com/v25.0/<MEDIA_ID>" \
-H "Authorization: Bearer <DUALHOOK_API_KEY>"
Response:
{
"success": true
}
Security and Compliance
- Treat media content routes and Dualhook API keys as sensitive data.
- Do not log bearer keys or media bodies.
- 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. Do not automatically retry message sends.
- Add idempotent job keys so repeated webhook events do not duplicate downloads.
- Dualhook streams media without persistence or caching and excludes media content and Meta download URLs from operational logs.