Video translation API for 135+ languages

Upload one video and get it back in every language you need. The video translation REST API transcribes the speech, translates it and dubs it, then returns the translated video, subtitle files and the translated text for review.
135+ target languages
Subtitles in .srt and .vtt
REST + Python SDK
one upload, every language
OAuth 2.0
# 1. exchange client credentials for a token (valid 1 hour)
curl -X POST https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=client_credentials"

# 2. upload the video once - YouTube, Drive, S3, Vimeo or direct URL
curl -X POST https://api.rask.ai/api/library/v1/media/link \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"link": "https://youtu.be/...", "name": "Q3 launch"}'

# 3. one project per target language - they run in parallel
for lang in es-mx de-de ja-jp pt-br; do
  curl -X POST https://api.rask.ai/v2/projects \
    -H "Authorization: Bearer $TOKEN" \
    -d "{\"video_id\": \"$VIDEO_ID\", \"dst_lang\": \"$lang\"}"
done
GET /v2/projects/{project_id}
polling, 10s
# Poll each project until merging_done, then collect the files.
while :; do
  curl -s https://api.rask.ai/v2/projects/$ID \
    -H "Authorization: Bearer $TOKEN" \
    | jq '{status, translated_video, translation_srt_path}'
  sleep 10
done
Used by global teams
Capabilities

What the video translation API does in one project

Automatically transcribe, translate and dub your videos through one API. Review the translated text, keep terminology consistent with glossaries and download the output format each platform needs. Add optional lip-sync, billed separately.

Translation into 135+ languages

Send a video and a target language to translate videos into es-mx, pt-br, fr-ca or any other supported locale. The source language is detected automatically.

Speaker detection and per-speaker voices

Speakers are separated automatically and each one gets a voice in the target language, so interviews and panels stay easy to follow. Override any assignment, or pass the count if you know it.

Original voices or AI voices

Use each speaker’s original voice with Instant Voice Clone, or reuse a saved Custom Voice Clone for a consistent presenter voice across videos. Both options are available in supported target languages; AI voice presets cover the rest.

Lip-sync

Enable lip sync to match mouth movement to the translated speech, as an optional task on any finished project, billed separately. Face detection runs first, so you apply it only where it will work.

Background audio preserved

Music, room tone and effects are separated from speech and mixed back under the new voice over, so viewers hear the original production in a different language.

Subtitles in .srt and .vtt

Every translated video comes with a subtitle file in both formats, in the target language and timed to the translated speech.

Terminology control with glossaries

Brand names, product names and technical terms translate the same way in every video and every language, or stay in the original language on purpose.

Translated text you can edit

Fetch the transcript with the source and translated text side by side, correct a line or a timestamp, then regenerate. Reviewers fix the text, and nobody records audio again.

Scale without limits

No rate limits, no concurrency quota, no per-key throttle. Send your full catalogue and translate large volumes into multiple languages in parallel.
See it in action

What the video translation API returns

The same clip, translated through the workflow on this page. Original speakers on the source, translated speech in French, German, Portuguese and Spanish, background audio intact.
EN flag
En
FR flag
Fr
DE flag
De
PT flag
Pt
ES flag
Es
Workflow

Three steps from upload to translated video

Creating a project starts the translation. Use the /generate endpoint later to re-dub a project after you edit it.
1

Upload your video

Send a file as multipart form data, or post a link from YouTube, Google Drive, S3, Vimeo or any direct download URL. You get a media id and the technical metadata before you spend anything.

POST /api/library/v1/media/link
2

Create a project per language

Pass the media id as video_id and a target language. Create one project for each language you need from the same upload, with your own transcript or a glossary if you have one.

POST /v2/projects
3

Assign voices and re-dub

Read status until it reaches merging_done, then download the translated video and the subtitle files for that language.

GET /v2/projects/{project_id}
Processing time varies by project. For batch translation, create one project per target language from the same upload, track each one through the API and download the files when it is complete.
Built around you

Need more than the catalogue? Talk to our team.

New languages, custom voices, your own delivery method, higher throughput: when a video translation integration needs something outside the public catalogue, our team reviews your requirements and the available options.

Languages and voices

Need a language or voice outside the public catalogue? Talk to our team about your requirements and the available options.

Delivery and integration

Webhooks, push into your own queue, delivery straight to your S3, custom endpoints. Tell us how your pipeline expects to be fed.

Volume and throughput

Batch sizes, target languages per action and processing priority are all contract terms, not fixed product limits.

Security and hosting

Data residency, SSO and SAML, retention rules and security review support are handled as part of enterprise onboarding.
Use cases

Who uses a video translation API

Platforms with video inside

LMS and customer-education platforms, creator and video platforms, webinar and virtual event tools, video hosting and workflow SaaS, digital adoption platforms, live shopping and AI video tools that help users create videos or generate videos from text. Your users already upload video content to your product. With the API they translate videos in the same place, into multiple languages, and video translation becomes one of your paid features.

Localization and production agencies

Connect video translation to the delivery workflow you already run and keep your human review step. Linguists review the translated text segment by segment, so your team delivers more client languages with the same people.

In-house continuous video production

International retail and e-commerce, global franchises, media publishers, corporate universities. Build translation into your publishing workflow, so training videos and product content reach every market in different languages, and regenerate a language version whenever the source video changes.
Customer stories

Real teams, measurable results

How companies localize video with Rask, in their own numbers.
arrow
arrow
Code

Video translation API code examples

One complete example in each language: authenticate, upload once, create a project per target language, wait, collect the translated video and subtitle files.
# pip install git+ssh://[email protected]/braskai/rask-sdk.git@main
import asyncio
from rask_sdk import clients, enums, schemas

TARGETS = ["es-mx", "de-de", "ja-jp", "pt-br"]

async def translate(client, video_id, lang):
    job = await client.create_project(
        data=schemas.ProjectCreate(video_id=video_id, dst_lang=lang))
    while job.status is not enums.ProjectStatus.MERGING_DONE:
        await asyncio.sleep(10)
        job = await client.get_project(project_id=job.id)
    return job

async def main():
    client = clients.RaskSDKClient(client_id=CLIENT_ID, client_secret=CLIENT_SECRET)

    video = await client.create_media_link(
        data=schemas.MediaCreateLink(link="https://youtu.be/..."))
    while video.status is not enums.MediaStatus.READY:
        await asyncio.sleep(5)
        video = await client.get_media(media_id=video.id)

    jobs = await asyncio.gather(*(translate(client, video.id, l) for l in TARGETS))
    for j in jobs:
        print(j.dst_lang, j.translated_video, j.translation_srt_path)

asyncio.run(main())
github.com/braskai/rask-sdk
Python 3.8+, async
import time, requests

AUTH = "https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token"
API  = "https://api.rask.ai"

token = requests.post(AUTH, auth=(CLIENT_ID, CLIENT_SECRET),
                      data={"grant_type": "client_credentials"}).json()["access_token"]
h = {"Authorization": f"Bearer {token}"}

video = requests.post(f"{API}/api/library/v1/media/link", headers=h,
                      json={"link": "https://youtu.be/..."}).json()
while video["status"] != "ready":
    time.sleep(5)
    video = requests.get(f"{API}/api/library/v1/media/{video['id']}", headers=h).json()

ids = [requests.post(f"{API}/v2/projects", headers=h,
                     json={"video_id": video["id"], "dst_lang": lang}).json()["id"]
       for lang in ["es-mx", "de-de", "ja-jp", "pt-br"]]

for pid in ids:
    while (p := requests.get(f"{API}/v2/projects/{pid}", headers=h).json())["status"] != "merging_done":
        time.sleep(10)
    print(p["dst_lang"], p["translated_video"], p["translation_vtt_path"])
requests + polling
no SDK required
// no dependencies, Node 18+ global fetch
const API = 'https://api.rask.ai';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

const auth = await fetch('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token', {
  method: 'POST',
  headers: { Authorization: 'Basic ' + btoa(`${CLIENT_ID}:${CLIENT_SECRET}`) },
  body: new URLSearchParams({ grant_type: 'client_credentials' }),
}).then((r) => r.json());

const h = { Authorization: `Bearer ${auth.access_token}`, 'Content-Type': 'application/json' };
const get = (path) => fetch(API + path, { headers: h }).then((r) => r.json());
const post = (path, body) => fetch(API + path, { method: 'POST', headers: h, body: JSON.stringify(body) }).then((r) => r.json());

let video = await post('/api/library/v1/media/link', { link: 'https://youtu.be/...' });
while (video.status !== 'ready') { await sleep(5000); video = await get(`/api/library/v1/media/${video.id}`); }

const results = await Promise.all(['es-mx', 'de-de', 'ja-jp', 'pt-br'].map(async (dst_lang) => {
  let p = await post('/v2/projects', { video_id: video.id, dst_lang });
  while (p.status !== 'merging_done') { await sleep(10000); p = await get(`/v2/projects/${p.id}`); }
  return p;
}));

results.forEach((p) => console.log(p.dst_lang, p.translated_video, p.translation_srt_path));
fetch, Node 18+
plain HTTP
<?php
use GuzzleHttp\Client;

$http = new Client(['base_uri' => 'https://api.rask.ai']);
$json = fn($r) => json_decode($r->getBody(), true);

$auth = $json((new Client)->post('https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
    ['auth' => [$clientId, $clientSecret], 'form_params' => ['grant_type' => 'client_credentials']]));
$h = ['Authorization' => 'Bearer ' . $auth['access_token']];

$video = $json($http->post('/api/library/v1/media/link',
    ['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']]));
while ($video['status'] !== 'ready') {
    sleep(5);
    $video = $json($http->get("/api/library/v1/media/{$video['id']}", ['headers' => $h]));
}

foreach (['es-mx', 'de-de', 'ja-jp', 'pt-br'] as $lang) {
    $p = $json($http->post('/v2/projects', ['headers' => $h,
        'json' => ['video_id' => $video['id'], 'dst_lang' => $lang]]));
    while ($p['status'] !== 'merging_done') {
        sleep(10);
        $p = $json($http->get("/v2/projects/{$p['id']}", ['headers' => $h]));
    }
    echo $lang, ' ', $p['translation_srt_path'], PHP_EOL;
}
POST /v2/projects
OAuth 2.0 client credentials
<?php
use GuzzleHttp\Client;

$http = new Client(['base_uri' => 'https://api.rask.ai']);

$auth = json_decode((new Client)->post(
    'https://rask-prod.auth.us-east-2.amazoncognito.com/oauth2/token',
    ['auth' => [$clientId, $clientSecret],
     'form_params' => ['grant_type' => 'client_credentials']]
)->getBody(), true);

$h = ['Authorization' => 'Bearer ' . $auth['access_token']];

$media = json_decode($http->post('/api/library/v1/media/link',
    ['headers' => $h, 'json' => ['link' => 'https://youtu.be/...']])->getBody(), true);

$project = json_decode($http->post('/v2/projects',
    ['headers' => $h, 'json' => ['video_id' => $media['id'], 'dst_lang' => 'es-mx']])->getBody(), true);

while ($project['status'] !== 'merging_done') {
    sleep(10);
    $project = json_decode($http->get("/v2/projects/{$project['id']}",
        ['headers' => $h])->getBody(), true);
}
Guzzle 7
plain HTTP
Python is the official SDK. The Node, PHP and cURL tabs are plain HTTP examples against the same endpoints.
Progress

How translation progress is reported

Each project moves through a documented state machine, so your users can follow the process in a real, staged progress bar for every language version. You only need to act on three groups.

Success, stop here

merging_done
Translation is complete. Fetch the project once more to retrieve the download links available for your project.

In progress, keep polling

created
uploading
transcription_started
separate_background_started
determine_speakers_started
translation_started
voiceover_started
merging_started
Plus the matching _done states.

Failure, stop and report

failed
upload_failed
transcription_failed
translation_failed
voiceover_failed
merging_failed
no_audio
no_words
forbidden_link
no_audio, no_words and forbidden_link are specific enough to show directly to your own user. Every error also returns a machine-readable slug for error handling.
Observed run, 3:47 source video, en → es-mx
GET /v2/projects/{project_id}
   0s  created
  11s  transcription_started
  87s  translation_started
  99s  voiceover_started
 154s  merging_started
 165s  merging_done

Or skip polling entirely

Point us at a webhook endpoint and every state transition arrives as a POST, so your queue reacts to each change the moment it happens. Webhook delivery is part of enterprise onboarding.
Read the docs
preserveAspectRatio="xMidYMid meet" aria-hidden="true" role="img">
Output

Translated video, audio and subtitles

Download the translated video and subtitles in SRT and VTT for every target language. On eligible plans, you can also download the translated voice on its own or mixed with the original background audio.
Field
Format
What it is
translated_video
MP4
The dubbed video, ready to publish
voiceover
WAV
Translated speech only, no background, for your own mix
translated_audio
WAV
Translated speech mixed with the original background audio
translation_srt_path
.srt
Subtitles in the target language
translation_vtt_path
.vtt
Same subtitles as WebVTT, for web players
original_video
MP4
Your source file as stored, for reference
Control

Review the translated text, then re-dub only what changed

Start with automatic translation or bring your own approved translation as an SRT file when creating the project. Review the script before publishing and regenerate only what changes. API re-dubbing is billed on the changed segments.

Segment-level editing

Segment-level editing
Every project exposes its transcript as segments, with the source text and the translated text side by side, so a correction takes one patch request.
Fetch the transcript and its segments
Patch the source text and we re-translate it
Patch the translated text directly to keep your own wording
Adjust timestamps, add segments, delete segments
Reassign the voice attached to any speaker

Glossaries for terminology

Glossaries for terminology
Attach a glossary to a project so brand names, product names and technical terms translate the same way in every language version, or stay untranslated on purpose.

A glossary covers one language pair and applies across all regional variants of that target language, so one Spanish glossary serves es-mx and es-es alike. The project records glossary_version, so later edits never silently change finished work.
Input

Supported file formats

Upload any of seven video and four audio formats, or send a URL. An unsupported file is rejected by content type before any translation minutes are charged.

Video

7 formats
.mp4
.mov
.mkv
.avi
.webm
.m4v
.3gp

Audio

4 formats
.mp3
.wav
.flac
.m4a

Metadata before you spend

The media endpoint returns duration, file size, video codec, frame rate, resolution, audio codec, sample rate and channel layout. Validate a file and estimate cost in advance, because video translation is billed by the minute.
Security and compliance

Ready for your security review

Brask Inc holds SOC 2 Type II and operates under GDPR, and publishes live control status in its Trust Center. Your video content is processed in a closed AI environment.

Certifications

SOC 2 Type II
GDPR
CAI and C2PA member

Encryption

TLS 1.2 in transit
AES-256 at rest
SSE-S3 managed keys
Key rotation at least every 12 months

Your content

Closed AI environment
Never used to train general models
Full export, no lock-in

Access

SSO and SAML
Role-based access control
OAuth 2.0 client credentials

Enterprise

Data residency options
Custom SLAs
Dedicated account manager

Voice rights

Synthetic voices with usage rights
Consent-based voice cloning
AI safety controls, human in the loop
Comparison

Rask API vs a pipeline you build yourself

A text translation API translates characters. Video translation also needs speech recognition, timing, voices and mixing. Here is the same capability, assembled two ways.
What you need
Rask API
Assembled from parts
Transcription, translation, synthesis, mixing
One call
Three to four vendors and the code between them
Timing the translation to the video
Included
Your own alignment logic
Speaker detection and per-speaker voices
Included
A diarization vendor plus your own voice-assignment logic
Background music and effects preserved
Included
A source-separation step you build and tune
Subtitles in .srt and .vtt
Included
Generated from your own timing data
Lip-sync
Optional, billed separately
A separate vendor
Fixing one translated line
Re-dub that segment, billed for that segment
Re-run the pipeline, pay for the file
Terminology consistency
Versioned glossaries
Pre and post-processing you maintain
Rate limits
None
Whatever your strictest vendor enforces
A language outside the catalogue
Discussed with our team
Depends on each vendor
FAQ

Video translation API: common questions

Can't find what you're looking for? Contact sales.

Is there an API that translates videos automatically?

How do I get API access and an API key?

How do I authenticate with the video translation API?

Is the API synchronous or asynchronous?

What are the rate limits?

How many languages can I translate videos into?

Can I translate one video into multiple languages at once?

How long does video translation take?

What file formats are supported?

Do I get subtitles as well as a translated video?

Can I edit the translated text before publishing?

Can ChatGPT translate a video?

How much does video translation cost?

Start dubbing in one afternoon

Make your first request today, and talk to us when you need volume terms or a language nobody else has.