API documentation

Use the REST API to create projects, track each target language, and download completed files.

Base URLhttps://api.dittodub.com

Try the API

Send a request from this page. Your API key remains in this browser tab and is not saved or included when you copy the agent setup. Start with List locales, which does not require authentication.

No request is sent until you press the button.

Dubbing

All dubbing routes start with /v1/dubbing. Check /v1/usage before paid work. Search for an existing project or connected YouTube video before creating one. Poll the project until each requested language completes.

Create a project, then poll it for status and files.

Use upload and download routes for local source files and completed deliverables.

GET/v1/dubbing/locales

Choose languages

GET/v1/dubbing/youtube/videos

Find source videos

GET/v1/usage

Check available credits

POST/v1/dubbing/projects

Create a project

GET/v1/dubbing/projects

Find existing projects

GET/v1/dubbing/projects/{id}

Read status and files

POST/v1/dubbing/projects/{id}/languages

Preview or add languages

GET/v1/dubbing/locales

List supported locales

Lists the source and target locales accepted by the Dubbing API. No authentication required.

Parameters

No request parameters.

Request
curl "https://api.dittodub.com/v1/dubbing/locales"
Example response
{
  "data": [
    { "locale": "en_us", "display_name": "English - United States" },
    { "locale": "es_mx", "display_name": "Spanish - Mexico" },
    { "locale": "fr_fr", "display_name": "French - France" }
  ]
}
GET/v1/dubbing/youtube/videos

List connected YouTube videos

Lists recent or matching videos from YouTube channels connected to the workspace. If a video already has a DittoDub project, the response includes it.

Parameters

channel_idquerystring

A connected channel ID. When omitted, DittoDub uses the workspace's primary channel.

queryquerystring

Search video titles or provide an exact YouTube video ID.

limitqueryinteger

Number of videos to return, from 1 to 50. Defaults to 20.

Request
curl "https://api.dittodub.com/v1/dubbing/youtube/videos?query=launch&limit=20" \
  --header "x-api-key: $DITTODUB_API_KEY"
Example response
{
  "data": {
    "connection_required": false,
    "channel": { "channel_id": "UC...", "title": "My channel" },
    "items": [
      {
        "youtube_video_id": "VIDEO_ID",
        "title": "Launch video",
        "url": "https://www.youtube.com/watch?v=VIDEO_ID",
        "duration_seconds": 487,
        "matching_project": {
          "project_id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
          "state": "verified",
          "target_locales": ["es_mx"]
        }
      }
    ]
  }
}
GET/v1/usage

Get workspace usage

Returns total, reserved, and currently available workspace credits and billable seconds. Check this before starting paid work.

Parameters

No request parameters.

Request
curl "https://api.dittodub.com/v1/usage" \
  --header "x-api-key: $DITTODUB_API_KEY"
Example response
{
  "data": {
    "credits_per_second": 93,
    "credits": {
      "total": 930000,
      "reserved": 93000,
      "available": 837000
    },
    "billable_seconds": {
      "total": 10000,
      "reserved": 1000,
      "available": 9000
    },
    "as_of": "2026-08-20T18:00:00.000Z"
  }
}
POST/v1/dubbing/projects

Create a dubbing project

Creates a dubbing project from a YouTube URL or uploaded file. DittoDub processes every target language inside that project.

Parameters

Idempotency-KeyheaderstringRequired

A unique key for this create request. Send the same key and body again to receive the original project.

namebodystringRequired

A human-readable project name, up to 100 characters.

external_idbodystring

Your own stable identifier for later lookup.

source_localebodylocaleRequired

The exact source locale returned by List locales.

target_localesbodylocale[]Required

One or more unique target locales.

max_billable_secondsbodyintegerRequired

If validated billable duration exceeds this value, DittoDub stops before processing or charging.

sourcebodyobjectRequired

Use { type: youtube, url } or { type: upload, file_name, size_bytes }.

Request
curl "https://api.dittodub.com/v1/dubbing/projects" \
  --request POST \
  --header "x-api-key: $DITTODUB_API_KEY" \
  --header "Idempotency-Key: launch-video-1042" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Launch video",
    "external_id": "video-1042",
    "source_locale": "en_us",
    "target_locales": ["es_mx", "fr_fr"],
    "max_billable_seconds": 1800,
    "source": {
      "type": "youtube",
      "url": "https://www.youtube.com/watch?v=VIDEO_ID"
    }
  }'
Example response
{
  "data": {
    "id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
    "external_id": "video-1042",
    "name": "Launch video",
    "status": "validating",
    "source_locale": "en_us",
    "target_locales": ["es_mx", "fr_fr"],
    "usage": {
      "max_billable_seconds": 1800,
      "billable_seconds": null,
      "charged_seconds": 0,
      "state": "pending_validation"
    },
    "languages": []
  }
}
GET/v1/dubbing/projects

List dubbing projects

Lists projects with cursor pagination. Filter by external ID or YouTube video ID to find a known project.

Parameters

limitqueryinteger

Number of projects to return, from 1 to 50. Defaults to 20.

cursorquerystring

The opaque next_cursor from the previous response.

external_idquerystring

Return projects with your external identifier.

youtube_video_idquerystring

Return projects created for this YouTube video ID.

queryquerystring

Search project names, external IDs, or an exact YouTube video ID.

Request
curl "https://api.dittodub.com/v1/dubbing/projects?limit=20" \
  --header "x-api-key: $DITTODUB_API_KEY"
Example response
{
  "data": [
    {
      "id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
      "name": "Launch video",
      "status": "processing",
      "target_locales": ["es_mx", "fr_fr"]
    }
  ],
  "page": {
    "has_more": true,
    "next_cursor": "eyJ2IjoxLCJjcmVhdGVkX2F0IjoiLi4uIn0"
  }
}
GET/v1/dubbing/projects/{project_id}

Get a dubbing project

Returns project status and usage, source transcript review status, progress for each language, publishing metadata, and completed files. Set include_transfer to true to refresh upload URLs.

Parameters

project_idpathUUIDRequired

The project ID returned when the project was created.

include_transferqueryboolean

Set false when you do not need refreshed upload URLs.

Request
curl "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID" \
  --header "x-api-key: $DITTODUB_API_KEY"
Example response
{
  "data": {
    "id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
    "status": "completed",
    "usage": {
      "max_billable_seconds": 1800,
      "billable_seconds": 487,
      "charged_seconds": 974,
      "state": "charged"
    },
    "languages": [
      {
        "locale": "es_mx",
        "status": "completed",
        "deliverables": [
          { "type": "audio", "format": "mp3", "download_url": "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID/download?locale=es_mx&type=audio" }
        ]
      }
    ]
  }
}
POST/v1/dubbing/projects/{project_id}/languages

Add languages to a project

Returns an exact quote for new target languages. The default preview does not charge or change the project. After approval, set preview_only to false to add them.

Parameters

project_idpathUUIDRequired

The existing project that should receive new languages.

target_localesbodylocale[]Required

Exact locales returned by List locales.

max_billable_secondsbodyintegerRequired

Limits billable seconds for the full request. If the quote exceeds it, DittoDub does not charge or add languages.

preview_onlybodyboolean

Defaults to true. Set false only after accepting the returned quote.

Idempotency-Keyheaderstring

Required when preview_only is false. Reuse the same key when retrying that accepted request.

Request
curl "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID/languages" \
  --request POST \
  --header "x-api-key: $DITTODUB_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "target_locales": ["de_de", "ja_jp"],
    "max_billable_seconds": 1800,
    "preview_only": true
  }'
Example response
{
  "data": {
    "addition": {
      "preview_only": true,
      "existing_locales": [],
      "new_locales": ["de_de", "ja_jp"],
      "billable_seconds": 974,
      "credits": 90582,
      "max_billable_seconds": 1800,
      "within_limit": true
    }
  }
}
POST/v1/dubbing/projects/{project_id}/transcript-review

Submit the source transcript for human review

Returns an exact quote or submits the English source transcript to Ditto Verified. It never sends a translated transcript. Preview the quote first, then submit with the approved spend ceiling.

Parameters

project_idpathUUIDRequired

The project whose English source transcript needs review.

max_billable_secondsbodyintegerRequired

Limits billable seconds for the review. If the project duration rounds above it, DittoDub does not submit or charge.

preview_onlybodyboolean

Defaults to true. Set false only after accepting the returned quote.

Idempotency-Keyheaderstring

Required when preview_only is false. Reuse the same key when retrying that accepted request.

Request
curl "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID/transcript-review"   --request POST   --header "x-api-key: $DITTODUB_API_KEY"   --header "Content-Type: application/json"   --data '{
    "max_billable_seconds": 1800,
    "preview_only": true
  }'
Example response
{
  "data": {
    "project": {
      "id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
      "transcript_review": {
        "requested": false,
        "status": "not_requested"
      }
    },
    "review": {
      "preview_only": true,
      "already_requested": false,
      "billable_seconds": 487,
      "credits": 45291,
      "max_billable_seconds": 1800,
      "within_limit": true,
      "charged_now_seconds": 0
    }
  }
}
GET/v1/dubbing/projects/{project_id}/download

Download a completed file

Returns a completed file through a stable authenticated URL. Audio and thumbnails redirect to short-lived storage URLs. DittoDub returns subtitle files directly.

Parameters

project_idpathUUIDRequired

The project that owns the deliverable.

localequerylocaleRequired

The completed target locale.

typequeryenumRequired

audio, subtitles, or thumbnail.

formatqueryenum

For subtitles only: srt or vtt. Defaults to vtt.

Request
curl --location \
  "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID/download?locale=es_mx&type=subtitles&format=vtt" \
  --header "x-api-key: $DITTODUB_API_KEY" \
  --output launch-video.es-MX.vtt
Example response
WEBVTT

00:00:00.000 --> 00:00:02.480
Bienvenidos a nuestro video de lanzamiento.
POST/v1/dubbing/projects/{project_id}/upload/complete

Complete an upload

Completes the project's multipart upload after all parts reach their presigned URLs, then queues source validation.

Parameters

project_idpathUUIDRequired

The upload project returned by Create project.

partsbodyarrayRequired

Every uploaded part_number and its ETag, in ascending order.

Request
curl "https://api.dittodub.com/v1/dubbing/projects/PROJECT_ID/upload/complete" \
  --request POST \
  --header "x-api-key: $DITTODUB_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "parts": [
      { "part_number": 1, "etag": "ETAG_FROM_UPLOAD_RESPONSE" }
    ]
  }'
Example response
{
  "data": {
    "id": "23fa9d79-cc42-4c82-90b8-2b7c78c57b31",
    "status": "validating",
    "source": { "type": "upload", "file_name": "launch-video.mp4" }
  }
}