curl --request PUT \
--url https://api-vod-express.syncwords.com/v1/projects/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Season 1, dubbed into Spanish"
}
'import requests
url = "https://api-vod-express.syncwords.com/v1/projects/{id}"
payload = { "description": "Season 1, dubbed into Spanish" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({description: 'Season 1, dubbed into Spanish'})
};
fetch('https://api-vod-express.syncwords.com/v1/projects/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": "01m3k8jnrdw509457nhz7w81bq",
"name": "Fishing Channel S01",
"description": null,
"buildVersion": "0.9.0-alpha1-2026-10-20T14-10Z-3f05aa",
"status": "running",
"files": {
"total": 3,
"pending": 1,
"processing": 0,
"done": 1,
"failed": 1,
"countedAt": "2026-09-28T06:15:00.000Z"
},
"startOnNewFiles": true,
"config": {
"sourceMedia": {
"@type": "S3FolderSource"
},
"transcription": {
"@type": "Speechmatics",
"language": "en"
},
"translations": [
{
"language": "es",
"engine": {
"@type": "Gemini"
},
"ttsOptions": {
"provider": {
"@type": "Deepdub",
"voice": "auto"
}
}
}
],
"outputs": [
{
"@type": "S3FolderOutput",
"items": [
{
"@type": "VideoFile",
"ext": "mp4",
"nameTemplate": "${name}.es.${ext}",
"useOriginalTracks": true,
"dubTracks": [
{
"language": "es",
"title": "Spanish"
}
]
}
]
}
]
},
"storage": {
"connection": null,
"path": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/",
"inputPath": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/input/",
"outputPath": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/output/",
"inputPrefix": null,
"outputPrefix": null
},
"meta": {
"createdAt": "2026-09-28T05:42:35.534Z",
"updatedAt": "2026-09-28T05:42:35.534Z",
"createdBy": {
"accountId": 141,
"accountName": "Acme Media",
"userId": null,
"userEmail": null,
"userFullName": null
},
"configLocked": false,
"messages": []
}
}
}{
"message": "Unauthenticated.",
"code": "unauthenticated"
}{
"message": [
"VOD Express is not enabled for your account."
],
"code": "vod_express_not_enabled"
}{
"message": "Project not found.",
"code": "project_not_found"
}{
"message": [
"The project's configuration is managed by SyncWords support and cannot be changed right now."
],
"code": "project_config_locked"
}{
"message": [
"The request body is too large."
],
"code": "payload_too_large"
}{
"message": [
"Send the body as JSON (Content-Type: application/json) or YAML (Content-Type: application/yaml)."
],
"code": "unsupported_media_type"
}{
"code": "validation_failed",
"message": "No translation has ttsOptions, so there is no dub to add: use useOriginalTracks for the input’s audio. (and 2 more errors)",
"errors": {
"/config/outputs/0/items/0/dubTracks/0/language": [
"No translation has ttsOptions, so there is no dub to add: use useOriginalTracks for the input’s audio."
],
"/config/outputs/0/items/0/nameTemplate": [
"The name template must contain ${name}, or every input would write the same file."
],
"/config/translations/0/language": [
"Language 'xx' is not supported by engine 'DeepL'"
]
}
}{
"message": [
"Too Many Attempts."
],
"code": "too_many_requests"
}{
"message": [
"Failed to stop the running processing service"
],
"code": "service_stop_failed"
}Update a project (PUT)
The same as PATCH: every field is optional, and a field sent replaces the stored one. A 422 with service_start_failed means the change was stored and the restarted service did not start.
Guide: Projects
curl --request PUT \
--url https://api-vod-express.syncwords.com/v1/projects/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Season 1, dubbed into Spanish"
}
'import requests
url = "https://api-vod-express.syncwords.com/v1/projects/{id}"
payload = { "description": "Season 1, dubbed into Spanish" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({description: 'Season 1, dubbed into Spanish'})
};
fetch('https://api-vod-express.syncwords.com/v1/projects/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"data": {
"id": "01m3k8jnrdw509457nhz7w81bq",
"name": "Fishing Channel S01",
"description": null,
"buildVersion": "0.9.0-alpha1-2026-10-20T14-10Z-3f05aa",
"status": "running",
"files": {
"total": 3,
"pending": 1,
"processing": 0,
"done": 1,
"failed": 1,
"countedAt": "2026-09-28T06:15:00.000Z"
},
"startOnNewFiles": true,
"config": {
"sourceMedia": {
"@type": "S3FolderSource"
},
"transcription": {
"@type": "Speechmatics",
"language": "en"
},
"translations": [
{
"language": "es",
"engine": {
"@type": "Gemini"
},
"ttsOptions": {
"provider": {
"@type": "Deepdub",
"voice": "auto"
}
}
}
],
"outputs": [
{
"@type": "S3FolderOutput",
"items": [
{
"@type": "VideoFile",
"ext": "mp4",
"nameTemplate": "${name}.es.${ext}",
"useOriginalTracks": true,
"dubTracks": [
{
"language": "es",
"title": "Spanish"
}
]
}
]
}
]
},
"storage": {
"connection": null,
"path": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/",
"inputPath": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/input/",
"outputPath": "s3://sw-vod-express/projects/141/01m3k8jnrdw509457nhz7w81bq/output/",
"inputPrefix": null,
"outputPrefix": null
},
"meta": {
"createdAt": "2026-09-28T05:42:35.534Z",
"updatedAt": "2026-09-28T05:42:35.534Z",
"createdBy": {
"accountId": 141,
"accountName": "Acme Media",
"userId": null,
"userEmail": null,
"userFullName": null
},
"configLocked": false,
"messages": []
}
}
}{
"message": "Unauthenticated.",
"code": "unauthenticated"
}{
"message": [
"VOD Express is not enabled for your account."
],
"code": "vod_express_not_enabled"
}{
"message": "Project not found.",
"code": "project_not_found"
}{
"message": [
"The project's configuration is managed by SyncWords support and cannot be changed right now."
],
"code": "project_config_locked"
}{
"message": [
"The request body is too large."
],
"code": "payload_too_large"
}{
"message": [
"Send the body as JSON (Content-Type: application/json) or YAML (Content-Type: application/yaml)."
],
"code": "unsupported_media_type"
}{
"code": "validation_failed",
"message": "No translation has ttsOptions, so there is no dub to add: use useOriginalTracks for the input’s audio. (and 2 more errors)",
"errors": {
"/config/outputs/0/items/0/dubTracks/0/language": [
"No translation has ttsOptions, so there is no dub to add: use useOriginalTracks for the input’s audio."
],
"/config/outputs/0/items/0/nameTemplate": [
"The name template must contain ${name}, or every input would write the same file."
],
"/config/translations/0/language": [
"Language 'xx' is not supported by engine 'DeepL'"
]
}
}{
"message": [
"Too Many Attempts."
],
"code": "too_many_requests"
}{
"message": [
"Failed to stop the running processing service"
],
"code": "service_stop_failed"
}Authorizations
A token from POST /token/create, made with your API key pair.
Path Parameters
The project id, a lowercase ULID.
^[0-9a-z]{26}$Body
2552000The processing instructions, validated against the schema of the project’s build. Shown here: build 0.9.0-alpha1-2026-10-20T14-10Z-3f05aa; GET /schema has any build’s.
Show child attributes
Show child attributes
Whether a new file starts a stopped project; see startOnNewFiles on create.
Where the project keeps its input and output folders: one of your storage connections — your own bucket — with a folder for each, or connectionId: null for SyncWords’ storage. Left out on create, your account’s default decides; left out on a change, nothing moves. A project on your own bucket reads its input folder and writes its output folder: no feed source, no feed outputs.
Show child attributes
Show child attributes
Response
OK
Show child attributes
Show child attributes