VideoDubber Developers API
Automate video and audio translation with the API at api.videodubber.ai— authentication, jobs, polling, rate limits, and official Python and JavaScript clients.
VideoDubber API
Programmatically translate video or audio by submitting a public media URL to api.videodubber.ai, then polling until the translated file is ready. Official Python and JavaScript clients handle auth, throttling, and polling.
| Base URL | https://api.videodubber.ai |
|---|---|
| Auth | Header x-api-key on every /api/p/* request |
| Python client | pip install videodubber — CLI + library |
| JavaScript client | npm install videodubber — CLI + library (Node.js 18+) |
| Full API reference | videodubber_client.md on GitHub |
Requirements
- A VideoDubber API key (included on paid plans)
- A stable, publicly reachable
httporhttpsURL to the source media - Python 3.10+ for the Python client (
requestsinstalled automatically) - Node.js 18+ for the JavaScript client (native
fetch)
Languages and voices
Product documentation
Quickstart
The fastest path is an official client — it handles throttling, retries, and polling. Or integrate directly with REST: create a job, save the pid, then poll status every 15 seconds until status is complete.
Python
bash
pip install videodubber export VIDEODUBBER_API_KEY="your-api-key" videodubber \ --file-url "https://example.com/video.mp4" \ --target-language Spanish \ --voice Elvira \ --output ./translated.mp4
JavaScript / TypeScript
bash
npm install videodubber export VIDEODUBBER_API_KEY="your-api-key" npx videodubber \ --file-url "https://example.com/video.mp4" \ --target-language Spanish \ --voice Elvira \ --output ./translated.mp4
REST (curl)
1. Create a translation job:
bash
export VIDEODUBBER_API_KEY="your-api-key"
curl -sS -X POST "https://api.videodubber.ai/api/p/jobs" \
-H "x-api-key: $VIDEODUBBER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_url": "https://example.com/video.mp4",
"filetype": "mp4",
"OriginalLanguage": "English",
"TargetLanguage": "Spanish",
"NumSpeakers": "1",
"projectname": "API Project",
"selectedvoices": ["Elvira"],
"speakers": ["Speaker 1"],
"audioshift": "0",
"translator": "auto",
"has_subtitle_file": "false",
"subtitle_language_type": "",
"glossary_id": "",
"bg1": "Auto (Not recommended)",
"bg2": "0",
"voice_cloning": false
}'Success returns HTTP 202 with a project id:
json
{
"status": "accepted",
"pid": "abc123...",
"project_path": "/path/on/server"
}2. Poll until complete:
bash
curl -sS "https://api.videodubber.ai/api/p/jobs/YOUR_PID/status" \ -H "x-api-key: $VIDEODUBBER_API_KEY"
When status is complete, download from output_urls.translated_media. Wait at least 12 seconds between API calls (15 s recommended) to stay under rate limits.
Authentication
Every request to /api/p/* endpoints must include your API key in the x-api-key header.
Getting an API key
API access is included on paid plans. Once subscribed:
- Log in to app.videodubber.ai
- Open API Keys in your account dashboard
- Click Generate API key and copy the key immediately — it is shown once
- Store the key securely (password manager or secrets vault)
Manage keys via the API
While authenticated with a logged-in session:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/p/api-key | Return existing key |
| POST | /api/p/api-key | Generate a new key |
| DELETE | /api/p/api-key | Delete existing key |
Using your key
| Method | How |
|---|---|
| Python CLI | export VIDEODUBBER_API_KEY="your-api-key" or pass --api-key |
| Python library | VideoDubberClient(api_key="your-api-key") |
| JavaScript / TypeScript | new VideoDubberClient({ apiKey: "your-api-key" }) |
| Node CLI | export VIDEODUBBER_API_KEY="your-api-key" or pass --api-key |
| REST / curl | Add header x-api-key: your-api-key on every /api/p/* request |
Optional base URL override (default https://api.videodubber.ai):
bash
export VIDEODUBBER_API_BASE="https://api.videodubber.ai" # or: --base-url "https://api.videodubber.ai"
Keep keys secret
How the workflow works
Two steps: submit a job with a public media URL, then poll status until translation finishes or fails.
POST /api/p/jobs
file_url, creates a project, and starts translation (job0). Returns HTTP 202 with pid.GET /api/p/jobs/{pid}/status
status is complete or failed. When complete, use output_urls.translated_media to download the result.POST /api/p/jobs
Endpoint: POST https://api.videodubber.ai/api/p/jobs
Required JSON fields
| Field | Description |
|---|---|
| file_url | Public HTTP(S) URL to source video or audio (max 20 GiB on paid accounts) |
| filetype | Extension without dot, e.g. "mp4", "mp3", "mov" |
| OriginalLanguage | Source language display name, or "unknown" for auto-detect |
| TargetLanguage | Target language display name, e.g. "Spanish", "French (France)" |
| NumSpeakers | "1", "1 (female)", "Auto Detect", or "2", "3", … |
| projectname | Label shown in the app (default: API Project) |
| selectedvoices | Array of voice display names for the target language |
| speakers | Array of speaker labels, e.g. ["Speaker 1"] |
Common optional fields
| Field | Default | Description |
|---|---|---|
| audioshift | "0" | Audio sync offset in milliseconds (string) |
| translator | "auto" | Translation backend hint |
| glossary_id | "" | Optional DeepL glossary UUID |
| bg1 | "Auto (Not recommended)" | Background sound handling |
| bg2 | "0" | Secondary background option |
| voice_cloning | false | Enable instant voice cloning |
| has_subtitle_file | "false" | Whether a subtitle file is provided |
| subtitle_language_type | "" | Subtitle language type when applicable |
Example request body
json
{
"file_url": "https://example.com/video.mp4",
"filetype": "mp4",
"OriginalLanguage": "English",
"TargetLanguage": "Spanish",
"NumSpeakers": "1",
"projectname": "API Project",
"selectedvoices": ["Elvira"],
"speakers": ["Speaker 1"],
"audioshift": "0",
"translator": "auto",
"has_subtitle_file": "false",
"subtitle_language_type": "",
"glossary_id": "",
"bg1": "Auto (Not recommended)",
"bg2": "0",
"voice_cloning": false
}Success response (HTTP 202)
json
{
"status": "accepted",
"pid": "abc123...",
"project_path": "/path/on/server"
}Save the pid
pid for all status polls. It is the project identifier on the server.GET /api/p/jobs/{pid}/status
Endpoint: GET https://api.videodubber.ai/api/p/jobs/{pid}/status
Poll until status is complete or failed.
Processing statuses
| Status | Meaning |
|---|---|
| processing | Job is running |
| Need | Queued, waiting for a worker |
| Taken_up | Worker picked up the job |
| complete | Finished — output URLs available |
| failed | Job failed — see response body for details |
When complete, the response includes output_urls.translated_media — a URL to download the translated file. The response may also include available_minutes for credit balance checks.
Rate limits
Limits apply per API key (x-api-key), not per IP address.
5 requests per minute
POST /api/p/jobs and GET /api/p/jobs/{pid}/status share the same limit bucket: 5 requests / minute. Exceeding the limit returns HTTP 429 Too Many Requests.Server limits
| Endpoint | Limit |
|---|---|
POST /api/p/jobs | 5 requests / minute |
GET /api/p/jobs/{pid}/status | 5 requests / minute (shared bucket) |
Polling interval
| Setting | Default | Minimum |
|---|---|---|
| Poll interval (CLI: --poll-interval) | 15 seconds | 12 seconds (enforced) |
Wait at least 12 seconds between any two /api/p/* calls. The official Python and JavaScript clients enforce this automatically. One typical job uses roughly 1 create + N status polls (e.g. a 5-minute job ≈ 21 calls at 15 s spacing).
Official client protections
1. Proactive throttling — waits until 12 s have passed since the last API call before each request.
2. Automatic retry on 429 — reads Retry-After from headers or JSON, sleeps, then retries (exponential backoff up to 120 s, 8 attempts by default).
Planning concurrent jobs
| Scenario | Safe? | Notes |
|---|---|---|
| One job, 15 s polling | Yes | Designed for this |
| Multiple parallel jobs, one API key | Risky | Shared 5/min limit |
| Polling every 5 s | No | Client clamps to 12 s minimum |
| 6+ job creates in one minute | No | Will hit 429 |
For multiple concurrent jobs, use separate API keys or serialize creates with ≥12 s between submits.
File limits
Source media must be reachable by the VideoDubber server over the public internet.
Source file requirements (paid accounts)
| Constraint | Limit |
|---|---|
| Max file size | 20 GiB |
| URL scheme | http or https only |
| YouTube page URLs | Not supported |
file_url must point directly to the media file (e.g. a signed S3/GCS link or direct .mp4 link). YouTube watch links are rejected with HTTP 400 (YouTube URLs are not supported).
Stable URLs
Failed to download file_url). Host media on a stable, publicly reachable URL before calling the API.Python CLI
Install the official PyPI package for throttling, 429 retries, polling, and optional download. Requires Python 3.10+.
Install
bash
pip install videodubber
Basic example
bash
export VIDEODUBBER_API_KEY="your-uuid-key"
videodubber \
--file-url "https://example.com/video.mp4" \
--original-language English \
--target-language Spanish \
--voice Elvira \
--output ./translated.mp4Multiple speakers
bash
videodubber \
--file-url "https://example.com/interview.mp4" \
--target-language French \
--num-speakers 2 \
--voice Denise \
--voice Henri \
--speaker "Speaker 1" \
--speaker "Speaker 2"JSON output (automation)
bash
videodubber \
--file-url "https://example.com/video.mp4" \
--target-language German \
--voice Katja \
--json \
--quietPrints the final status object to stdout; progress logs go to stderr unless --quiet.
Required CLI arguments
| Argument | Description |
|---|---|
| --file-url | Public HTTP(S) URL to source video or audio |
| --target-language | Target language display name, e.g. "Spanish" |
| --voice | Voice display name (repeat per speaker) |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Job completed successfully |
| 1 | API error, rate limit, timeout, job failed, etc. |
Full CLI reference
Using as a Python library
Install from PyPI:
bash
pip install videodubber
python
from videodubber import VideoDubberClient, TranslationJobParams
client = VideoDubberClient(api_key="your-uuid-key")
params = TranslationJobParams(
file_url="https://example.com/video.mp4",
target_language="Spanish",
original_language="English",
selectedvoices=["Elvira"],
speakers=["Speaker 1"],
filetype="mp4",
)
# Submit + poll until complete
status = client.translate_from_url(params, poll_interval=15, max_wait=3600)
print(status.translated_media_url)Library methods
| Method | Description |
|---|---|
| create_job_from_url(params) | Submit job only; returns { pid, status, ... } |
| get_job_status(pid) | Single status check; returns JobStatus |
| wait_for_job(pid, ...) | Poll until complete, failed, or timeout |
| translate_from_url(params, ...) | Create + wait (full workflow) |
| health() | GET / health check (no rate-limit throttle) |
Node.js CLI
Install the official npm package for throttling, 429 retries, polling, and optional download. Requires Node.js 18+.
Install
bash
npm install videodubber
Basic example
bash
export VIDEODUBBER_API_KEY="your-uuid-key"
npx videodubber \
--file-url "https://example.com/video.mp4" \
--original-language English \
--target-language Spanish \
--voice Elvira \
--output ./translated.mp4Multiple speakers
bash
npx videodubber \
--file-url "https://example.com/interview.mp4" \
--target-language French \
--num-speakers 2 \
--voice Denise \
--voice Henri \
--speaker "Speaker 1" \
--speaker "Speaker 2"JSON output (automation)
bash
npx videodubber \
--file-url "https://example.com/video.mp4" \
--target-language German \
--voice Katja \
--json \
--quietPrints the final status object to stdout; progress logs go to stderr unless --quiet.
Required CLI arguments
| Argument | Description |
|---|---|
| --file-url | Public HTTP(S) URL to source video or audio |
| --target-language | Target language display name, e.g. "Spanish" |
| --voice | Voice display name (repeat per speaker) |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Job completed successfully |
| 1 | API error, rate limit, timeout, job failed, etc. |
Full CLI reference
Using as a JavaScript / TypeScript library
Install from npm:
bash
npm install videodubber
javascript
import { VideoDubberClient } from "videodubber";
const client = new VideoDubberClient({ apiKey: "your-uuid-key" });
const status = await client.translateFromUrl({
fileUrl: "https://example.com/video.mp4",
targetLanguage: "Spanish",
originalLanguage: "English",
selectedVoices: ["Elvira"],
speakers: ["Speaker 1"],
filetype: "mp4",
}, { pollInterval: 15, maxWait: 3600 });
console.log(status.translatedMediaUrl);Library methods
| Method | Description |
|---|---|
| createJobFromUrl(params) | Submit job only; returns { pid, status, ... } |
| getJobStatus(pid) | Single status check; returns JobStatus |
| waitForJob(pid, ...) | Poll until complete, failed, or timeout |
| translateFromUrl(params, ...) | Create + wait (full workflow) |
| health() | GET / health check (no rate-limit throttle) |
Common errors
Structured validation errors list accepted languages or voices in the response body.
| HTTP | Error | Cause |
|---|---|---|
| 400 | Missing required fields | Incomplete JSON body |
| 400 | Invalid TargetLanguage | Unknown target language name |
| 400 | Invalid voice | Voice not valid for target language |
| 400 | YouTube URLs are not supported | URL is not a direct media file |
| 403 | insufficient_credits | Not enough available minutes |
| 404 | project_not_found | Invalid or expired pid |
| 429 | Rate limited | More than 5 API calls per minute |
| 502 | Failed to download file_url | Server could not fetch your media URL |
The official clients print hints for validation errors (accepted languages, accepted voices). Other errors appear as error: ... on stderr.
Invalid language or voice
Integration tips
- Host media on a stable, publicly reachable URL before calling the API. The server downloads the file; private or expiring links often fail.
- Use the client's
--outputflag to save translated media locally after completion. - For long jobs, increase
--max-wait(default 3600 seconds / 1 hour). - Run with
--debugwhile integrating to inspect raw status JSON on each poll. - Do not run many parallel jobs on a single API key — they share the 5/minute rate limit.
- Pass regional language names exactly, e.g.
Spanish (Spain),French (France),English (US).
Need API access?
API access is included on paid plans. Generate a key from app.videodubber.ai or contact us for enterprise integrations.
© 2026 VideoDubber.ai - All rights reserved.