Docs home
ChannelDesk docs

Media and image templates

Upload images and videos or generate an image from a reusable template.


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/images uploads an image; required multipart fields are brand_id and file.
  • POST /api/v1/media/videos/uploads initializes 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/complete registers and attaches the successful upload.
  • GET /api/v1/image-templates lists brand and global templates.
  • GET /api/v1/image-templates/{id} returns template inputs.
  • POST /api/v1/image-templates/generate generates 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.