> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://murf.ai/api/docs/capabilities/dubbing/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://murf.ai/api/docs/_mcp/server. # Murf Dub Automation API Automate high-quality dubbing with realistic, multi-language support in bulk. Scale dubbing for apps, games, and videos in minutes. Integrate the API in your workflow seamlessly—globalizing your content faster than ever. #### [Get API Key](https://dub.murf.ai/api/manage-keys) Create high-quality dubbing in 28 languages in a fraction of the time --- #### Dub fast in bulk Upload and dub thousands of videos with rapid turnaround #### Automate dubbing workflows Streamline your dubbing process with automation, saving time and ensuring consistency across projects. #### Enterprise grade security Strict data handling policies, option for ephemeral storage and controlled retention periods ## Overview The Murf Dub Automation API can be used in two ways, depending on your needs: * **Transient (Temporary & Lightweight)**: Generate dubs instantly with temporary storage—output links expire in 72 hours, ensuring secure, API-only processing without storing data on the Murf platform. * **Persistent (Project-Based & Editable)**: Create and manage dubs via API or the Murf Dubbing platform UI, enabling editing, re-synthesis, QA checks, collaboration, refinements, and re-downloads if needed. ## Quickstart Use the following code snippets to get started with the Murf Dub Automation API. Creating a job creates a transient dub, while creating a job with a project allows you to create persistent dubs. #### Create a Job To automate dubbing of your files and keep the process API-based only, Create a job is recommended. These dubs expire after 72 hours and cannot be edited through UI. #### Getting Started Generate an API key [here](https://dub.murf.ai/api/manage-keys) > **Warning** > > API Key for Murf Dub Automation API is different from the one used for other Murf services (like TTS). Make sure to use the key generated from the MurfDub platform. #### Create a Job ```py # pip install murf from murf import MurfDub client = MurfDub( api_key="YOUR_API_KEY", # Not required if you have set the environment variable MURFDUB_API_KEY ) file_path = "PATH_TO_YOUR_FILE" # Path to the file you want to dub create_response = client.dubbing.jobs.create( target_locales=["fr_FR"], # Specify the languages you want to dub in file_name="File Name", # Name of the file for your reference file=open(file_path, "rb"), priority="LOW" # file_url="URL_TO_YOUR_FILE", # Optional: Use `file_url` instead of `file` if you want to dub a publicly accessible file # webhook_url="WEBHOOK_URL", # Optional: URL to receive webhook notifications on job status changes # webhook_secret="YOUR_WEBHOOK_SECRET", # Optional: Secret to validate the webhook ) print("Job created successfully:", create_response) ``` ```js import fs from "fs"; import FormData from "form-data"; import axios from "axios"; async function createJob() { const filePath = "PATH_TO_YOUR_FILE"; const url = "https://api.murf.ai/v1/murfdub/jobs/create"; const form = new FormData(); // Read the file as a stream and append it to the form const fileStream = fs.createReadStream(filePath); form.append("file", fileStream, "hello_world.mp4"); // Add file name explicitly form.append("file_name", "hello_world.mp4"); form.append("priority", "LOW"); form.append("target_locales", "fr_FR"); form.append("target_locales", "de_DE"); try { const response = await axios.post(url, form, { headers: { "api-key": "YOUR_API_KEY", }, }); console.log(response.data); } catch (error) { console.error(error.response ? error.response.data : error.message); } } createJob(); ``` ```curl curl -X POST https://api.murf.ai/v1/murfdub/jobs/create \ -H "api-key: api-key" \ -H "Content-Type: multipart/form-data" \ -F file=@ \ -F target_locales="target_locales" \ -F priority="LOW" ``` In the response, you will receive a job ID. This ID is used to check the status of the job and to download the dubbed file once the job is completed. ### Response (200) ```json { "dubbing_type": "AUTOMATED", "file_name": "File Name", "priority": "LOW", "job_id": "DKJl13am4p3NZ", "target_locales": [ "fr_FR" ] } ``` #### Check Job Status After creating a job, you can check its status using the job ID returned in the response. > **Info** > > This step is not required if you have set a webhook URL in the job creation step. The webhook will notify you when the job is completed. ```py from murf import MurfDub client = MurfDub( api_key="YOUR_API_KEY", # Not required if you have set the environment variable MURFDUB_API_KEY ) status_res = client.dubbing.jobs.get_status( job_id="job_id", ) print("Job status:", status_res) ``` ```js const url = 'https://api.murf.ai/v1/murfdub/jobs/YOUR_JOB_ID/status'; const options = {method: 'GET', headers: {'api-key': 'api-key'}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```curl curl https://api.murf.ai/v1/murfdub/jobs/YOUR_JOB_ID/status \ -H "api-key: api-key" ``` Once the job is completed, you can use the `download_url` from the job status response to download the dubbed file. ### Response (200) ```json { "job_id": "DKJl13am4p3NZ", "status": "COMPLETED", "download_details": [ { "locale": "fr_FR", "status": "COMPLETED", "download_url": "URL_TO_DOWNLOAD_FILE", "download_srt_url": "URL_TO_DOWNLOAD_SRT_FILE" } ], "credits_used": 1, "credits_remaining": 99 } ``` #### Create a Job with a Project To collaborate on dubs, edit, re-synthesize, or perform QA checks, frequently refine scripts, Project based dubbing is recommended. The jobs will also appear in the Murf Dubbing platform UI as well. #### Getting Started Generate an API key [here](https://dub.murf.ai/api/manage-keys) > **Warning** > > API Key for Murf Dub Automation API is different from the one used for other Murf services (like TTS). Make sure to use the key generated from the MurfDub platform. #### Create a Project Create a project where you can manage your dubbing jobs. You can skip this step if you already have a project. There are two types of dubbing available: * **Automated**: Fast dubbing delivery with AI translations. This is ideal for projects that require quick turnaround times and do not need human oversight. * **QA**: In-house experts ensure precise translations and voiceovers, with the option to edit and re-synthesize. This is ideal for high-stakes projects requiring human oversight. ```py # pip install murf from murf import MurfDub client = MurfDub( api_key="YOUR_API_KEY", # Not required if you have set the environment variable MURFDUB_API_KEY ) client.dubbing.projects.create( name="HolaPeppa", dubbing_type="AUTOMATED", target_locales=["es_ES"], # Specify the languages you want to dub in ) print("Project created successfully:", create_response) ``` ```js import axios from "axios"; const url = "https://api.murf.ai/v1/murfdub/projects/create"; const options = { method: "POST", headers: { "api-key": "YOUR_API_KEY", "Content-Type": "application/json", }, }; const payload = { name: "HolaPeppa", dubbing_type: "AUTOMATED", target_locales: ["es_ES"], }; try { const data = await axios.post(url, payload, options); console.log(data.data); } catch (error) { console.error(error); } ``` ```curl curl -X POST https://api.murf.ai/v1/murfdub/projects/create \ -H "api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "HolaPeppa", "dubbing_type": "AUTOMATED", "target_locales": [ "es_ES" ] }' ``` In the response, you will receive a project ID. This ID can be used to create dubbing jobs within the project. ### Response (200) ```json { "project_id": "project_id", "dubbing_type": "AUTOMATED", "target_locales": [ "target_locales" ], "name": "name", "description": "description", "source_locale": "source_locale" } ``` #### Create a Job Use a project ID to create a job. The mentioned file will be dubbed according to the project settings. ```py from murf import MurfDub client = MurfDub( api_key="YOUR_API_KEY", # Not required if you have set the environment variable MURFDUB_API_KEY ) file_path = "PATH_TO_YOUR_FILE" # Path to the file you want to dub create_response = client.dubbing.jobs.create_with_project_id( file_name="PeppaGoesToLondon", # Name of the file for your reference file=open(file_path, "rb"), project_id="P01743659288722XYZAB", # ID of the project that you want to associate the job with priority="LOW" # file_url="URL_TO_YOUR_FILE", # Optional: Use `file_url` instead of `file` if you want to dub a publicly accessible file # webhook_url="WEBHOOK_URL", # Optional: URL to receive webhook notifications on job status changes # webhook_secret="YOUR_WEBHOOK_SECRET", # Optional: Secret to validate the webhook ) print("Job created successfully:", create_response) ``` ```js import fs from "fs"; import FormData from "form-data"; import axios from "axios"; async function createJob() { const filePath = "PATH_TO_YOUR_FILE"; const url = "https://api.murf.ai/v1/murfdub/jobs/create-with-project-id"; const form = new FormData(); const fileStream = fs.createReadStream(filePath); form.append("file", fileStream, "peppa_goes_to_london_ep1.mp4"); form.append("file_name", "peppa_goes_to_london_ep1"); form.append("priority", "LOW"); form.append("project_id", "P01743659288722XYZAB"); try { const response = await axios.post(url, form, { headers: { "api-key": "YOUR_API_KEY", }, }); console.log(response.data); } catch (error) { console.error(error.response ? error.response.data : error.message); } } createJob(); ``` ```curl curl -X POST https://api.murf.ai/v1/murfdub/jobs/create-with-project-id \ -H "api-key: YOUR-API-KEY" \ -H "Content-Type: multipart/form-data" \ -F file=@ \ -F project_id="P01743659288722XYZAB" ``` In the response, you will receive a job ID. This ID is used to check the status of the job and to download the dubbed file once the job is completed. ### Response (200) ```json { "dubbing_type": "AUTOMATED", "file_name": "file_name", "priority": "LOW", "job_id": "job_id", "target_locales": [ "target_locales" ], "file_url": "file_url", "source_locale": "source_locale", "warning": "warning", "webhook_url\"": "webhook_url" } ``` #### Check Job Status After creating a job, you can check its status using the job ID returned in the response. > **Info** > > This step is not required if you have set a webhook URL in the job creation step. The webhook will notify you when the job is completed. ```py from murf import MurfDub client = MurfDub( api_key="YOUR_API_KEY", # Not required if you have set the environment variable MURFDUB_API_KEY ) status_res = client.dubbing.jobs.get_status( job_id="job_id", ) print("Job status:", status_res) ``` ```js const url = 'https://api.murf.ai/v1/murfdub/jobs/YOUR_JOB_ID/status'; const options = {method: 'GET', headers: {'api-key': 'api-key'}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```curl curl https://api.murf.ai/v1/murfdub/jobs/YOUR_JOB_ID/status \ -H "api-key: api-key" ``` Once the job is completed, you can use the `download_url` from the job status response to download the dubbed file. ### Response (200) ```json { "job_id": "job_id", "status": "status", "project_id": "project_id", "download_details": [ { "locale": "locale", "status": "status", "error_message": "error_message", "download_url": "download_url", "download_srt_url": "download_srt_url" } ], "credits_used": 1000000, "credits_remaining": 1000000, "failure_reason": "failure_reason", "failure_code": "failure_code" } ``` ## Languages Here are all the source and destination languages offered by Murf Dub Automation API in both types of dubbing: #### Automated | Source Languages (22) | Destination Languages (26) | | ------------------------------ | ------------------------------ | | Auto Detect | English (US & Canada) (en\_US) | | English (US & Canada) (en\_US) | English (UK) (en\_UK) | | English (UK) (en\_UK) | English (India) (en\_IN) | | English (India) (en\_IN) | English (Scotland) (en\_SCOTT) | | English (Scotland) (en\_SCOTT) | English (Australia) (en\_AU) | | English (Australia) (en\_AU) | French (fr\_FR) | | French (fr\_FR) | German (de\_DE) | | German (de\_DE) | Spanish (Spain) (es\_ES) | | Spanish (Spain) (es\_ES) | Spanish (Mexico) (es\_MX) | | Spanish (Mexico) (es\_MX) | Italian (it\_IT) | | Italian (it\_IT) | Portuguese (Brazil) (pt\_BR) | | Portuguese (Brazil) (pt\_BR) | Polish (pl\_PL) | | Polish (pl\_PL) | Hindi (hi\_IN) | | Hindi (hi\_IN) | Korean (ko\_KR) | | Korean (ko\_KR) | Tamil (ta\_IN) | | Japanese (ja\_JP) | Bengali (bn\_IN) | | Mandarin (Chinese) (zh\_CN) | Japanese (ja\_JP) | | Dutch (nl\_NL) | Mandarin (Chinese) (zh\_CN) | | Finnish (fi\_FI) | Dutch (nl\_NL) | | Russian (ru\_RU) | Finnish (fi\_FI) | | Turkish (tr\_TR) | Russian (ru\_RU) | | Ukrainian (uk\_UA) | Turkish (tr\_TR) | | | Danish (da\_DK) | | | Indonesian (id\_ID) | | | Romanian (ro\_RO) | | | Norwegian (nb\_NO) | #### QA | Source Languages (22) | Destination Languages (19) | | ------------------------------ | ------------------------------ | | Auto Detect | English (US & Canada) (en\_US) | | English (US & Canada) (en\_US) | English (UK) (en\_UK) | | English (UK) (en\_UK) | English (India) (en\_IN) | | English (India) (en\_IN) | English (Scotland) (en\_SCOTT) | | English (Scotland) (en\_SCOTT) | English (Australia) (en\_AU) | | English (Australia) (en\_AU) | French (fr\_FR) | | French (fr\_FR) | German (de\_DE) | | German (de\_DE) | Spanish (Spain) (es\_ES) | | Spanish (Spain) (es\_ES) | Spanish (Mexico) (es\_MX) | | Spanish (Mexico) (es\_MX) | Italian (it\_IT) | | Italian (it\_IT) | Portuguese (Brazil) (pt\_BR) | | Portuguese (Brazil) (pt\_BR) | Polish (pl\_PL) | | Polish (pl\_PL) | Hindi (hi\_IN) | | Hindi (hi\_IN) | Korean (ko\_KR) | | Korean (ko\_KR) | Tamil (ta\_IN) | | Japanese (ja\_JP) | Bengali (bn\_IN) | | Mandarin (Chinese) (zh\_CN) | Japanese (ja\_JP) | | Dutch (nl\_NL) | Mandarin (Chinese) (zh\_CN) | | Finnish (fi\_FI) | Dutch (nl\_NL) | | Russian (ru\_RU) | | | Turkish (tr\_TR) | | | Ukrainian (uk\_UA) | | ## API Limits API usage and rate limits are determined by your pricing plan. If you need higher limits, you can upgrade to a higher-tier plan. | Plan | Free | Pay-as-you-go | Enterprise | | ---------------- | --------------------- | --------------------- | ------------------------------- | | **Concurrency** | up to 5 | up to 5 | 15 (based on custom requests) | | **Video Length** | up to 1 hour | up to 1 hour | up to 1 hour | | **Resolution** | up to 1080p (Full HD) | up to 1080p (Full HD) | up to 1080p (Full HD) | | **QA** | - | - | Yes (using Project ID endpoint) | | **Watermark** | Yes | No | No | You can [contact us](https://murf.ai/murf-dub?form=popup\&utm_source=dub_platform) for custom requirements. ## Troubleshooting Below are some common errors you might encounter while using the Murf Dub Automation API, along with their descriptions and possible solutions: | Error Code | Description | Solution | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | `INSUFFICIENT_CREDITS` | Insufficient credits, please purchase additional credits to continue. [Purchase Credits](https://dub.murf.ai/) | Purchase additional credits from the Murf platform. | | `CREDITS_EXHAUSTED` | Your credits have been exhausted, please purchase additional credits to continue. [Purchase Credits](https://dub.murf.ai/) | Purchase additional credits from the Murf platform. | | `LANGUAGE_NOT_SUPPORTED` | The specified language is not yet supported. | Use a supported language. Refer to the [Languages](#languages) section for supported options. | | `SPEECH_NOT_PRESENT` | No speech detected in the audio. | Ensure the audio contains clear speech and try again. | | `SOURCE_LANGUAGE_MISMATCH` | Source language does not match the provided language. | Verify the source language and ensure it matches the provided language. | | `WEBHOOK_ERROR` | An error occurred while calling the mentioned webhook. Please use the Job Status API to fetch the Dub. | Verify the webhook URL and ensure it is reachable. Use the Job Status API as a fallback. | | `SERVER_ERROR` | Processing failed, please contact support. [Help Center](https://help.murf.ai/) | Contact Murf support for assistance. | ## FAQ #### What's the difference between using /jobs/create and /jobs/create-with-project-id ? `/jobs/create-with-project-ID`: The jobs (Dubs) appears in the Murf platform UI. You can edit, re-synthesize, or perform QA checks on the dubbing. The resulting audio files are stored permanently (subject to renewal or manual deletion). `/jobs/create` (no project ID) : The job does not appear on the platform; it’s purely API-based. Output links expire after 72 hours and cannot be edited through the UI. Perfect for one-off, high-security needs or quick tests. #### How do I bulk upload my entire library? You can programmatically loop through your file list and call the relevant job-creation endpoint for each file. This can be done by giving a public link to the video/audio or uploading it locally through multipart form-data(recommended for security). For large-scale operations, you may batch your requests to manage concurrency or network throughput efficiently. #### What service-level agreements (SLAs) apply to the Bulk Dubbing API? We typically offer 99% uptime. For premium-tier customers, higher availability SLAs may be negotiated. Processing speed depends on file length, concurrency levels, and subscription tier. Advanced or premium plans may grant higher throughput or priority in the dubbing queue. #### How do I pay for the dubbing services? Each dubbing consumes credits based on the minutes and number of languages. You can track how many credits you’ve used, how many remain, and get alerts when approaching limits on our usage dashboard. #### What happens if a dub fails? You’ll receive an HTTP error code and/or a webhook payload indicating the failure reason (e.g., insufficient credits, unsupported file format, file corruption). For project-based jobs, you can see the failure reason in the platform. For ephemeral jobs, you’ll only see it via the API response or webhook. #### Can I edit an uploaded dub? Yes, for project-based jobs: The Murf platform enables script, timing, or voice changes. You can finalize the result and re-download. For ephemeral jobs, editing is not available at the moment as there is no persistent record in the platform and the link is deleted after 72 hours. #### Is the API usage gated by my price plan? Yes: Different plans have varying concurrency limits and advanced features (such as QA checks). You can contact our sales team or view your plan details in the platform to see upgrade options. ## Docs - [Webhooks](https://murf.ai/api/docs/capabilities/dubbing/webhooks.md): Receive real-time notifications on job completion