VOD Upload

How do I offer my customers the ability to upload a video?

This guide covers the three upload flows the Dacast API supports today. Pick one, request credentials from the API, then push the file to storage. Encoding is asynchronous: the file is not playable the moment the upload HTTP call returns.

📘

All examples use https://developer.dacast.com as the API host. Authenticate with X-Api-Key and send X-Format: default. JSON request bodies must include Content-Type: application/json.

Which upload method should I use?

Methodupload_type / endpointsBest forHow you get the VOD id
AjaxPOST /v2/vod with "upload_type": "ajax"Browser forms (file picker → direct upload)Not in the init response. Find the VOD in the list (see below).
cURLPOST /v2/vod with "upload_type": "curl"Server-side uploads of typical file sizesInit returns an id and a signed curl-command. Do not treat the init id as the final VOD id - resolve it from the list after the PUT.
Multipart/v2/vod/upload/init-multipart, /signatures/multipart, /complete-multipartLarge files (including > 5 GB)complete-multipart returns vod_id.

Ajax and cURL go through Create Video. Multipart is a separate three-endpoint flow: Initiate, Get presigned URLs, Complete.

For a browser product you typically only need a file selector and a start-upload button. Title, description, splashscreen, and thumbnail can be set after the VOD exists.


Ajax: browser upload to storage

1. Request an upload signature

curl -X POST "https://developer.dacast.com/v2/vod" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default" \
  -H "Content-Type: application/json" \
  -d "{\"source\":\"yourFileNameHere.mp4\",\"upload_type\":\"ajax\",\"title\":\"My video\",\"auto_encoding\":true}"
const headers = new Headers();
headers.append('X-Api-Key', 'insertYourApiKeyHere');
headers.append('X-Format', 'default');
headers.append('Content-Type', 'application/json');

const init = {
  method: 'POST',
  headers,
  body: JSON.stringify({
    source: 'yourFileNameHere.mp4',
    upload_type: 'ajax',
    title: 'My video',
    auto_encoding: true
  })
};

fetch('https://developer.dacast.com/v2/vod', init)
  .then((response) => response.json())
  .then((fields) => {
    // fields: acl, bucket, key, policy, success_action_status, x-amz-*
  });

Useful body fields (see Create Video):

  • source - the filename being uploaded (required).
  • upload_type - "ajax".
  • auto_encoding - start encoding after the file lands in storage.
  • callback_url - optional. If set, Dacast POSTs file_id and title to that URL when processing finishes. A callback is not required; you can poll the API instead.
  • title - optional display name for the VOD. If omitted, the asset is named after source. You can still change it later with PUT /v2/vod/{id}.

A successful response looks like:

{
  "acl": "private",
  "bucket": "upload.dacast.com",
  "key": "vod/b21c25ef-1d75-9789-6a92-d8ba13c53a86/none/9f5becc4-7db9-e49f-646a-14e198ddd748",
  "policy": "…",
  "success_action_status": "201",
  "x-amz-algorithm": "AWS4-HMAC-SHA256",
  "x-amz-credential": "AKIA…/20211104/us-east-1/s3/aws4_request",
  "x-amz-date": "20211104T102930Z",
  "x-amz-signature": "ad538afc…"
}
🚧

This response is not a VOD record. There is no usable video id here. The last segment of key is also not the final VOD id.

2. POST the file to the bucket from the signature

Use bucket from the response as the host (https://{bucket}). Do not send bucket as a form field - it is not part of the signed form.

Send every other field from the signature, then file last. Include x-amz-algorithm. A successful upload typically returns 201 (success_action_status).

curl -X POST "https://{bucket}" \
  --form "key=vod/b21c25ef-1d75-9789-6a92-d8ba13c53a86/none/9f5becc4-7db9-e49f-646a-14e198ddd748" \
  --form "acl=private" \
  --form "success_action_status=201" \
  --form "policy=…" \
  --form "x-amz-algorithm=AWS4-HMAC-SHA256" \
  --form "x-amz-credential=AKIA…/20211104/us-east-1/s3/aws4_request" \
  --form "x-amz-date=20211104T102930Z" \
  --form "x-amz-signature=ad538afc…" \
  --form "file=@localfilename"
const formdata = new FormData();
formdata.append('key', fields.key);
formdata.append('acl', fields.acl);
formdata.append('success_action_status', fields.success_action_status);
formdata.append('policy', fields.policy);
formdata.append('x-amz-algorithm', fields['x-amz-algorithm']);
formdata.append('x-amz-credential', fields['x-amz-credential']);
formdata.append('x-amz-date', fields['x-amz-date']);
formdata.append('x-amz-signature', fields['x-amz-signature']);
formdata.append('file', fileInput.files[0]); // must be last

fetch('https://' + fields.bucket, { method: 'POST', body: formdata })
  .then((response) => {
    // expect 201
  });

3. Resolve the VOD id and wait until it is online

Indexing can lag (up to 60s). List videos by the title you sent on create (or by source if you did not send title) and pick the newest row:

curl "https://developer.dacast.com/v2/vod?page=1&per_page=25&title=My%20video" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default"

Then:

  1. Take id from the matching item (filter by creation_date if several files share the same name).
  2. Poll Lookup video until online is true and renditions are present. Encoding is not finished when the S3 POST returns.
  3. Optionally update metadata later with Update video: PUT /v2/vod/{id}.

If you passed callback_url, Dacast will POST multipart/form-data with file_id and title when processing completes. Treat that as a convenience, not as the only way to learn the id.


cURL: server-side upload

Use this when the file is already on your server and you want a signed PUT.

1. Request a signed upload command

curl -X POST "https://developer.dacast.com/v2/vod" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default" \
  -H "Content-Type: application/json" \
  -d "{\"source\":\"yourFileNameHere.mp4\",\"upload_type\":\"curl\"}"

Response shape:

{
  "curl-command": "curl -T yourFileNameHere.mp4 'https://…presigned…'",
  "id": "5f62bc1f-6c9e-c9d0-b985-2ac2e8f70924",
  "url": "https://…presigned…"
}
🚧

Generate a fresh curl-command for every upload. Reusing a signed URL fails authentication.

The id in this response is not reliably the final VOD id. After the file PUT, find the asset with List videos (filter by title / source filename) the same way as ajax.

2. PUT the file

Run the returned curl-command (or PUT to url) with the real file path in place of the placeholder. The signed request uses the PUT verb, not a form POST.

If the generated command omits Content-Type, add one that matches the file (for example video/quicktime for .mov).

3. Resolve the VOD id

Same as ajax: list by title, then poll lookup until the video is online.


Multipart: large files

Use multipart for large videos (required above 5 GB). Storage is chosen server-side (today this may be Wasabi or AWS). Always PUT to the presigned URLs you receive - do not hardcode upload.dacast.com.

Full reference: Initiate, Get presigned URLs, Complete.

Rules

  • Each part must be at least 5 MB, except the last part.
  • At most 100 part signatures per signatures call. Request another range if the file has more parts.
  • Upload parts with PUT. Save the ETag header from each response (keep the quotes if storage returned them).

1. Initiate

curl -X POST "https://developer.dacast.com/v2/vod/upload/init-multipart" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"yourFileNameHere.mp4\"}"

You get s3_path and uploader_id. Optional: destination_folders_ids, recipe_id.

2. Request presigned URLs

curl -X POST "https://developer.dacast.com/v2/vod/upload/signatures/multipart" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default" \
  -H "Content-Type: application/json" \
  -d "{\"from_part_number\":1,\"to_part_number\":4,\"s3_path\":\"s3://…\",\"uploader_id\":\"…\"}"

Response: { "presigned_urls": [ "https://…", "https://…" ] }.

3. PUT each part and collect ETags

curl -i -X PUT --data-binary @part_1.bin "https://presigned-url-for-part-1"

Read ETag from the response headers.

4. Complete

curl -X POST "https://developer.dacast.com/v2/vod/upload/complete-multipart" \
  -H "X-Api-Key: insertYourApiKeyHere" \
  -H "X-Format: default" \
  -H "Content-Type: application/json" \
  -d "{\"s3_path\":\"s3://…\",\"uploader_id\":\"…\",\"ordered_etags\":[\"etag-part-1\",\"etag-part-2\"]}"

Response: { "vod_id": "bd91b7d4-50aa-4a20-9326-db4f21c1e77b" }.

Encoding can still take time after complete. Poll Lookup video until renditions are ready.


After the video exists

Store the VOD id (and your end-user id, if this is a multi-tenant CMS). Then: