Media and image templates
Images use multipart upload. Videos use direct provider upload so large files do not pass through the application server.
POST /api/v1/media/imagesuploads an image; required multipart fields arebrand_idandfile.POST /api/v1/media/videos/uploadsinitializes MP4, MOV, WebM, or M4V upload up to 500 MB.- Upload the bytes to the provider URL returned by initialization.
POST /api/v1/media/videos/uploads/completeregisters and attaches the successful upload.GET /api/v1/image-templateslists brand and global templates.GET /api/v1/image-templates/{id}returns template inputs.POST /api/v1/image-templates/generategenerates and attaches an image.
Upload an image
Send POST /api/v1/media/images as multipart/form-data. brand_id and file are required. Include content_id to attach it immediately.
curl -X POST "https://app.channeldesk.io/api/v1/media/images" \
+ -H "Authorization: Bearer <access_token>" \
+ -F "brand_id=42" \
+ -F "content_id=1496" \
+ -F "description=Summer campaign hero" \
+ -F "[email protected]"Direct video upload
Supported extensions are MP4, MOV, WebM, and M4V. Maximum size is 524288000 bytes (500 MB).
Step 1 - initialize
POST /api/v1/media/videos/uploads
{
"brand_id": 42,
"content_id": 1496,
"file_name": "summer-reel.mp4",
"mime_type": "video/mp4",
"file_size": 18765432
}The response contains direct, provider upload instructions, immutable object metadata, and meta. Stop and show reason when direct is false.
Step 2 - upload bytes to the provider
Use the returned method, URL, and every returned header exactly. Never send the ChannelDesk bearer token to the storage provider.
curl -X PUT "<upload.url>" \
+ -H "Content-Type: video/mp4" \
+ --upload-file "summer-reel.mp4"Step 3 - complete
After a successful provider response, call POST /api/v1/media/videos/uploads/complete with object metadata returned by initialization.
{
"brand_id": 42,
"content_id": 1496,
"file_size": 18765432,
"extension": "mp4",
"name": "summer-reel_ab12cd34.mp4",
"path": "brands/42/media/",
"public_url": "https://cdn.example.com/brands/42/media/summer-reel_ab12cd34.mp4"
}The API verifies that name and path match public_url. Do not construct or modify these values in the app.
Generate an image from a template
Load GET /api/v1/image-templates?brandId=42&type=post and GET /api/v1/image-templates/{id} to build the dynamic form.
Send POST /api/v1/image-templates/generate:
{
"brand_id": 42,
"content_id": 1496,
"template_id": 12,
"inputs": {
"headline": "Summer offer",
"discount": "15%"
}
}Refresh attachments
After image upload, video completion, or generation, call GET /api/v1/contents/{id} and use its media array as the authoritative state.