Dubbing

Dub a video into another language over the Direct API with dub_media on Morphic Dub, quote it first, follow the generation, and read the settled charge.

dub_media dubs one recording into another language in its speakers' own voices. On Morphic Dub (mdl_h2z5a7af7y50) it takes a video up to 10 minutes long and returns the same video, the same length, with every speaker re-voiced in their own voice and their close-ups lip-synced to the new speech. It is a long generation, up to about 13 minutes per minute of video, and its charge is an estimate at start that is settled to what the run spent.

Choose the model

Modelmodel_idTakesReturns
Morphic Dubmdl_h2z5a7af7y50one video, up to 10 minutesthe video, dubbed and lip-synced
ElevenLabs Dubbingsee the catalogone audio or video file, up to 30 minutesan audio file, the length of the source

Omit model_id and a video runs on your organization's default dubbing model, which is Morphic Dub on paid plans. Name mdl_h2z5a7af7y50 to pin it. An audio file, or a video longer than 10 minutes, is refused on Morphic Dub with 422 naming the limit; send those to ElevenLabs Dubbing.

Inputs

FieldRequired
media_asset_idyesthe video to dub: an asset id from list_assets, a finished generation's asset, or a public HTTPS URL (see Passing your own media)
target_languageyesone BCP-47 tag, such as hi, es or pt-BR. One language per call; for several markets, make one call per language. Morphic Dub dubs a regional variant in its main language and says so in the response's notice
source_languagenothe language spoken, as a BCP-47 tag. Omit to have it detected; set it when the audio is noisy or mixes languages
keytermsnonames, places and brands the translation keeps as spoken, each up to 5 words
voice_modenooriginal (the default) keeps every speaker's own voice; assigned speaks each person in a catalog voice. Morphic Dub only
voicesnowho speaks in which voice, up to 20 entries; needs voice_mode: "assigned". See Assign voices
source_transcript_asset_idnoyour own timed SRT of the speech, in the spoken language, used instead of transcribing; on Morphic Dub needs voice_mode: "assigned", on ElevenLabs Dubbing needs source_language
translation_asset_idnoyour own timed SRT of the lines in the target language, used instead of translating; on Morphic Dub needs voice_mode: "assigned", on ElevenLabs Dubbing goes only with source_transcript_asset_id
model_idnomdl_h2z5a7af7y50 for Morphic Dub. A call carrying voice_mode: "assigned", voices or either SRT with no model named runs on Morphic Dub; naming another model with them is refused
project_idyesthe project the dub lands in, from list_projects

A video with no audio stream, or a target_language equal to the source_language you set, is refused before anything is charged.

Assign voices, bring your own transcript or translation

By default every speaker keeps their own voice and Morphic transcribes and translates the speech. With voice_mode: "assigned", each person speaks in a voice from Morphic's voice catalog instead, and you can hand in your own text. On Morphic Dub, a transcript or translation of your own needs assigned: the original voices are dubbed in one pass that takes no cast and no text, and a call that sends either with original is refused with 422 naming the field.

  1. List the voices a dub can assign: list_voices with model_id: "mdl_h2z5a7af7y50". It needs no scope and returns each voice's voice_id. Catalog voices only; a voice of your organization is refused
  2. For a speaker named by a face image or a clip, pass the asset's id or its HTTPS URL as speaker_asset_id; otherwise describe them in speaker_description (up to 120 characters, none of ;, = or "). Exactly one of the two per entry, and each speaker once; speakers you leave out get a fitting catalog voice
  3. For your own SRT, pass its HTTPS URL or the id of an SRT document already in your library (list_assets shows it) as source_transcript_asset_id (spoken language) or translation_asset_id (target language); a URL is added to the project as a document before the dub starts, like any other file by URL. The two fields take two different files
{
  "input": {
    "media_asset_id": "01928f4e-…",
    "target_language": "es",
    "voice_mode": "assigned",
    "voices": [
      { "speaker_asset_id": "https://cdn.example.com/host-face.jpg", "voice_id": "0192b1c0-…" },
      { "speaker_description": "the narrator", "voice_id": "0192b1c1-…" }
    ],
    "source_transcript_asset_id": "https://cdn.example.com/interview.en.srt",
    "translation_asset_id": "https://cdn.example.com/interview.es.srt",
    "model_id": "mdl_h2z5a7af7y50",
    "project_id": "01928f4e-…"
  }
}

Both voice modes are charged at the same rate.

Over MCP the two SRT fields work on ElevenLabs Dubbing too, with model_name: "ElevenLabs Dubbing" and no voices: every speaker keeps their own voice, source_language is required, since the engine cannot detect the language from a transcript, and translation_asset_id goes only beside source_transcript_asset_id, with a translated cue over every transcript cue. When most cues start with a speaker label, such as Mira: …, the labels decide who speaks when, one voice per speaker. ElevenLabs Dubbing has no model_id, so over the Direct API a dub with your own text runs on Morphic Dub.

Quote it first

A dub is priced on the length of the source, per language. plan_media prices the call without starting it; on Morphic Dub the quote is the estimate the start will charge, which settlement can later move.

{
  "input": {
    "steps": [
      { "id": "dub", "tool_name": "dub_media", "arguments_json": "{\"media_asset_id\":\"01928f4e-…\",\"target_language\":\"hi\",\"model_id\":\"mdl_h2z5a7af7y50\"}" }
    ]
  }
}

See Quote before you spend for the full call.

Start the dub

curl -s https://mcp.morphic.com/v1/direct/tools/dub_media \
  -H "Authorization: Bearer $MORPHIC_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dub-interview-hi-1" \
  -d '{
        "input": {
          "media_asset_id": "https://cdn.example.com/interview.mp4",
          "target_language": "hi",
          "keyterms": ["Arjun", "Meera"],
          "model_id": "mdl_h2z5a7af7y50",
          "project_id": "01928f4e-…"
        }
      }'

The response is 202 Accepted:

{
  "result": {
    "generation_id": "0192a7b3-a1c4-7e02-8f9d-1a2b3c4d5e6f",
    "status": "queued",
    "model_id": "mdl_h2z5a7af7y50",
    "estimated_credits": 580,
    "credits_settle_on_output_duration": true
  },
  "billing": { "credits_charged": 580, "credits_are_final": false }
}

estimated_credits is the estimate charged now; credits_settle_on_output_duration: true says it will be settled.

Follow the generation

A dub on Morphic Dub takes up to about 13 minutes per minute of video, and a short clip takes longer than that ratio suggests, since the fixed stages cost the same whatever the length: a 50-second clip took 17 minutes. Do not poll from the start. Wait about 13 times the clip's length, then read with a long wait and back off from the poll_after_seconds each read carries.

sleep 660   # a 50 s clip: about 13 times its length
curl -s "https://mcp.morphic.com/v1/direct/generations/$GENERATION_ID?wait=45" \
  -H "Authorization: Bearer $MORPHIC_API_KEY"

A webhook spares you the loop: pass a registered webhook_id in the call body and Morphic calls your endpoint when the dub is final. Use the webhook as the main signal and an occasional poll as the safety net.

When the generation is succeeded, its assets hold the dubbed video. The response's notice is set when the dub ran on another input than the one given, such as a regional variant dubbed in its main language.

What it costs

Morphic Dub is billed on the source's length at your organization's API rates, per language:

  1. At start, the estimate is charged: estimated_credits, also billing.credits_charged
  2. When the dub finishes, the charge is settled to what the run actually spent. The settled amount can be below or above the estimate, but never more than three times it; past that, Morphic absorbs the rest
  3. Once the generation is final, billing.credits_charged is the settled net amount and credits_are_final is true. A dub that fails or is cancelled is refunded in full

Read the generation again once it is final for the settled amount; a webhook is sent only once it is. See Credits and usage for the ledger.


If you have any trouble or have any questions, feel free to reach out. We're happy to help. Write to us at support@morphic.com.

On this page