> For clean Markdown of any page, append `.md` to the page URL.
> For a complete documentation index, see https://docs.sarvam.ai/llms.txt.
> For full documentation content in one file, see https://docs.sarvam.ai/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sarvam.ai/_mcp/server.

# FAQs

> Frequently asked questions about the Sarvam AI Dubbing API. Get answers about languages, voice cloning, export formats, watermarks, polling, and troubleshooting.

Common questions about the [Dubbing API](/api/api-guides-tutorials/dubbing/overview). If yours isn't here, reach out on [Discord](https://discord.com/invite/5rAsykttcs).

## Pricing and billing

#### How much does dubbing cost?

Dubbing is billed per whole second of source media, multiplied by the number of target languages. On Starter, the default API rate is **₹40/min** when `editor_flow` is `false` (the default). See [Pricing](/api/getting-started/pricing#dubbing) for Pro, Enterprise, and the full rate table.

#### Why does \`editor\_flow: true\` cost more?

`editor_flow: true` enables the interactive editor workflow (manual review, chunk edits, and manual export triggers in Creator Studio). It is billed at the **editor-flow rate — ₹80/min on Starter**, which is **double** the standard API rate. It also suppresses auto-export, so `export-status` stays empty until exports are triggered manually. For programmatic integrations that just need dubbed files back, keep `editor_flow` at its default of `false`.

#### How do I estimate credits before starting a job?

Multiply source duration in whole seconds by the number of target languages, then apply the per-second rate for your plan and whether `editor_flow` is enabled. Example: a 60-second file into two languages at the Starter API rate (₹40/min) costs about ₹80 in credits (60 × 2 × ₹40/60).

## Getting started

#### Which host and auth header does dubbing use?

See the [API Reference](/api-reference/creative-agents-dubbing/create-dub) for the current base URL. Send your key in the `api-subscription-key` header, not `Authorization: Bearer`. Generate a key at [Key Management](https://dashboard.sarvam.ai/key-management) using the same email as your Sarvam account.

If you're using the Python SDK, none of this needs configuring: the client resolves the dubbing endpoint from its default environment, so `SarvamAI(api_subscription_key=...)` is enough. You do not need to pass a custom `SarvamAIEnvironment`.

#### Is there a single call that takes a file and returns a dub?

No. Dubbing runs as an asynchronous pipeline, so it's split across five steps: create the job, upload the media to the signed `upload_url`, `POST /start`, poll `live-status`, then read `export-status` for download URLs. In the Python SDK the upload step is `client.dubbing.upload()`. See the [Overview](/api/api-guides-tutorials/dubbing/overview#how-it-works) for the flow, and the [API Reference](/api-reference/creative-agents-dubbing/create-dub) for runnable code for each call.

#### What files can I upload?

Video as MP4, MOV, MKV, WebM, AVI, FLV, or WMV, and audio as WAV, MP3, or M4A. The file needs to be at least one second long and contain audible speech. The format is detected from the file's contents rather than its name, so the `.mp4` ending the signed upload URL does not constrain what you send.

#### How large or long can my media be?

It depends on your plan: 2 GB and 1 hour on Starter, 3 GB and 1 hour on Pro, and 4 GB and 4 hours on Business. Starter is the default, so assume those limits unless your account is on a higher plan; on Enterprise, check with your account team. Media over the limit is rejected when processing starts, not at upload time. See [What you can upload](/api/api-guides-tutorials/dubbing/overview#what-you-can-upload).

## Languages

#### Which languages are supported?

Twelve: English (`en-IN`), Hindi (`hi-IN`), Bengali (`bn-IN`), Gujarati (`gu-IN`), Kannada (`kn-IN`), Malayalam (`ml-IN`), Marathi (`mr-IN`), Odia (`or-IN`), Punjabi (`pa-IN`), Tamil (`ta-IN`), Telugu (`te-IN`), and Assamese (`as-IN`). The same set is valid for both `src_lang` and `target_langs`.

#### Do I need one job per target language?

No, and you shouldn't. `target_langs` is an array and a single job dubs into every language in it, from one upload and one `job_id`. See [Specify Language Codes](/api/api-guides-tutorials/dubbing/how-to/specify-language-codes).

## Voices and speakers

#### Does the dub keep the original speaker's voice?

Yes, by default. `voice_cloning` defaults to `true`, which preserves each original speaker's vocal identity in the target language. See [Choose a Voice](/api/api-guides-tutorials/dubbing/how-to/choose-a-voice).

#### How does Sarvam handle multiple speakers?

Set `num_speakers` to the number of distinct voices in the source (1 to 10, or `-1` to auto-detect); each is separated and cloned independently. The default is `1`, so a conversation left at the default is flattened into one voice. If you're unsure, round your estimate **up**, because under-specifying is audible and can only be fixed with a new job.

#### Can I use a preset voice instead of cloning?

Yes. Set `voice_cloning: false` and name a `voice_id` from the 15 preset voices, optionally with a `pace_preset`. This is single-speaker only, so multi-speaker jobs always clone. See [Choose a Voice](/api/api-guides-tutorials/dubbing/how-to/choose-a-voice).

## Translation quality

#### How do I control how formal the translation sounds?

Pass `register`. Accepted values are `formal`, `common-indic`, `classic-colloquial`, `modern-colloquial`, `academic`, and `auto`. See [Control Translation Tone](/api/api-guides-tutorials/dubbing/how-to/control-translation-tone).

#### What's the fastest way to review translation quality?

Add `srt` to `export_options` and read the subtitle file. It takes seconds versus watching the full dub, and it surfaces register and phrasing problems before you publish.

#### Can I change the register on an existing job?

No. Every setting is fixed at creation, and there is no update endpoint. To compare registers on the same source, create two jobs.

## Exports and downloads

#### What formats can I get back?

`export_options` accepts any combination of `video`, `audio`, and `srt`, produced for **each** target language. Omit it and you get video, audio, and MP3 — but never SRT, which you have to request explicitly. Pass it and only the formats you list are produced. Note that `audio` is uncompressed `.wav`; entries may also report an `export_type` of `mp3`, which is the same track re-encoded. See [Choose Export Formats](/api/api-guides-tutorials/dubbing/how-to/choose-export-formats).

#### I only asked for SRT. Can I get the video later?

Yes, and without re-dubbing or re-uploading. The translated audio already exists, so `POST /jobs/{job_id}/export-all?target_lang=...` produces the full video + audio + MP3 set for that language, and `POST /jobs/{job_id}/export` adds one specific format. Both reuse valid existing exports. See [Choose Export Formats](/api/api-guides-tutorials/dubbing/how-to/choose-export-formats#getting-a-format-you-didnt-request).

#### How long do download URLs stay valid?

Roughly 24 hours. They're signed and time-limited, so store the `job_id` and re-poll `export-status` for a fresh link rather than caching the URL.

#### What does \`is\_stale\` mean?

The translation chunks for that language were modified after the export completed, so the downloadable file no longer reflects the latest edits. Re-export before publishing.

#### How do I remove the watermark?

Pass `disable_watermark: true` at job creation. It defaults to `false`, applies to video exports only, and cannot be changed after the job exists. See [the watermark section](/api/api-guides-tutorials/dubbing/how-to/choose-export-formats#the-watermark-on-video-exports).

## Statuses and polling

#### What are the possible job statuses?

`not_started`, `queued`, `in_progress`, `completed`, `failed`, `partial_failure`, and `deleted`. A freshly created job is `not_started` until you call `start`. Individual exports carry their own separate status: `in_progress`, `completed`, or `failed`. See [Job Lifecycle](/api/api-guides-tutorials/dubbing/job-lifecycle).

#### What is \`partial\_failure\`?

Some target languages succeeded and others didn't. It's uncommon, but treat it as a terminal state alongside `completed` and `failed`, so the languages that did work still get published. Inspect per-language state in `live-status` and per-entry `status` in `export-status`.

#### How often should I poll?

The API does not specify a required polling interval, so pick one that suits your workload and back off for long files. As general guidance: always cap total wait time, and poll from a background worker rather than an HTTP request handler. If you need a value to start from, treat something like 15 seconds as an example to tune against your own file lengths, not a recommended setting.

## Troubleshooting

#### Why is my job still \`not\_started\` or \`queued\`?

Both mean a step is still outstanding on your side. `not_started` means `POST /jobs/{job_id}/start` was never called — creating a job does not start it. `queued` means it was started but the media was never uploaded to `upload_url`, so there is nothing to process. See [Job Lifecycle](/api/api-guides-tutorials/dubbing/job-lifecycle).

#### Why did my job fail soon after starting?

Media is checked once processing begins rather than while it uploads, so an unsupported format, a corrupt or truncated file, or one with no audible audio only surfaces at that point — storage accepts the bytes either way. Read `error_message` on the job for the specific reason.

#### What causes a 422 on language codes?

Check Odia. The dubbing service uses **`or-IN`**, and `od-IN` is rejected. Also confirm every code is in the list of twelve above, and that `src_lang` does not also appear in `target_langs`.

#### I set \`voice\_id\` but the dub came back in the original voice. Why?

Because cloning is on by default and takes precedence. A preset voice needs `voice_cloning: false` alongside `voice_id`; without it both `voice_id` and `pace_preset` are discarded without an error. Multi-speaker jobs always clone, since one preset voice cannot represent several speakers. See [Choose a Voice](/api/api-guides-tutorials/dubbing/how-to/choose-a-voice).

#### Why would \`export-status\` be empty on a completed job?

Usually timing: the job reaches `completed` when the dubbing pipeline finishes, and exports are triggered at that moment rather than before it, so a poll that lands in between sees nothing yet. Keep polling. Auto-export is best-effort per language, so if entries never appear for one language you can trigger them yourself with `POST /jobs/{job_id}/export-all?target_lang=...`.

#### Why would some exports be missing from the response?

Check `limit`. It defaults to `5`, and entries beyond the limit are not returned, so a job with 2 languages × 3 formats gets only five of its six entries. Pass an explicit `limit` above `languages × formats` (maximum `100`).

#### What causes a 403 when uploading to \`upload\_url\`?

The signed URL expired. Check `data.expires_in_hours` from the create response and upload promptly; if it's lapsed, create a new job for a fresh URL. Also make sure you're sending `x-ms-blob-type: BlockBlob` and a correct `Content-Type`, and **not** sending your API key to that URL.

#### What should I include in a support request?

The `job_id`. It's how a dub is traced end to end, so log it on every call for the job.

## Related

* [Dubbing Overview](/api/api-guides-tutorials/dubbing/overview)
* [Credits & Rate Limits](/api/getting-started/ratelimits)