Start Translation
curl --request POST \
--url https://api.voicecheap.ai/v1/translate \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"targetLanguage": "<string>",
"originalLanguage": "<string>",
"projectName": "<string>",
"webhookUrl": "<string>",
"numberOfSpeakers": "<string>",
"brandVocabulary": "<string>",
"removeFillerWords": true,
"sourceSrt": "<string>",
"keepBackgroundMusic": true,
"keepOriginalVoice": true,
"originalVoiceVolume": 123,
"voiceIsolatorOption": "<string>",
"subtitles": true,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": true,
"lipsyncPro": true,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceCloningSettings": {
"stability": 123,
"similarity": 123,
"speakerBoost": 123
},
"translationTimeSkips": "<string>"
}
'import requests
url = "https://api.voicecheap.ai/v1/translate"
payload = {
"targetLanguage": "<string>",
"originalLanguage": "<string>",
"projectName": "<string>",
"webhookUrl": "<string>",
"numberOfSpeakers": "<string>",
"brandVocabulary": "<string>",
"removeFillerWords": True,
"sourceSrt": "<string>",
"keepBackgroundMusic": True,
"keepOriginalVoice": True,
"originalVoiceVolume": 123,
"voiceIsolatorOption": "<string>",
"subtitles": True,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": True,
"lipsyncPro": True,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceCloningSettings": {
"stability": 123,
"similarity": 123,
"speakerBoost": 123
},
"translationTimeSkips": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
targetLanguage: '<string>',
originalLanguage: '<string>',
projectName: '<string>',
webhookUrl: '<string>',
numberOfSpeakers: '<string>',
brandVocabulary: '<string>',
removeFillerWords: true,
sourceSrt: '<string>',
keepBackgroundMusic: true,
keepOriginalVoice: true,
originalVoiceVolume: 123,
voiceIsolatorOption: '<string>',
subtitles: true,
subtitlesSource: '<string>',
lipSyncMode: '<string>',
activeSpeakerDetectionEnabled: true,
lipsyncPro: true,
voiceMode: '<string>',
voiceId: '<string>',
voiceCloningSettings: {stability: 123, similarity: 123, speakerBoost: 123},
translationTimeSkips: '<string>'
})
};
fetch('https://api.voicecheap.ai/v1/translate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.voicecheap.ai/v1/translate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'targetLanguage' => '<string>',
'originalLanguage' => '<string>',
'projectName' => '<string>',
'webhookUrl' => '<string>',
'numberOfSpeakers' => '<string>',
'brandVocabulary' => '<string>',
'removeFillerWords' => true,
'sourceSrt' => '<string>',
'keepBackgroundMusic' => true,
'keepOriginalVoice' => true,
'originalVoiceVolume' => 123,
'voiceIsolatorOption' => '<string>',
'subtitles' => true,
'subtitlesSource' => '<string>',
'lipSyncMode' => '<string>',
'activeSpeakerDetectionEnabled' => true,
'lipsyncPro' => true,
'voiceMode' => '<string>',
'voiceId' => '<string>',
'voiceCloningSettings' => [
'stability' => 123,
'similarity' => 123,
'speakerBoost' => 123
],
'translationTimeSkips' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.voicecheap.ai/v1/translate"
payload := strings.NewReader("{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.voicecheap.ai/v1/translate")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.voicecheap.ai/v1/translate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"projectId": "<string>",
"estimatedDuration": 123
}Translation
Start Translation
Upload a video or audio file and start a new translation project
Start Translation
curl --request POST \
--url https://api.voicecheap.ai/v1/translate \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"targetLanguage": "<string>",
"originalLanguage": "<string>",
"projectName": "<string>",
"webhookUrl": "<string>",
"numberOfSpeakers": "<string>",
"brandVocabulary": "<string>",
"removeFillerWords": true,
"sourceSrt": "<string>",
"keepBackgroundMusic": true,
"keepOriginalVoice": true,
"originalVoiceVolume": 123,
"voiceIsolatorOption": "<string>",
"subtitles": true,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": true,
"lipsyncPro": true,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceCloningSettings": {
"stability": 123,
"similarity": 123,
"speakerBoost": 123
},
"translationTimeSkips": "<string>"
}
'import requests
url = "https://api.voicecheap.ai/v1/translate"
payload = {
"targetLanguage": "<string>",
"originalLanguage": "<string>",
"projectName": "<string>",
"webhookUrl": "<string>",
"numberOfSpeakers": "<string>",
"brandVocabulary": "<string>",
"removeFillerWords": True,
"sourceSrt": "<string>",
"keepBackgroundMusic": True,
"keepOriginalVoice": True,
"originalVoiceVolume": 123,
"voiceIsolatorOption": "<string>",
"subtitles": True,
"subtitlesSource": "<string>",
"lipSyncMode": "<string>",
"activeSpeakerDetectionEnabled": True,
"lipsyncPro": True,
"voiceMode": "<string>",
"voiceId": "<string>",
"voiceCloningSettings": {
"stability": 123,
"similarity": 123,
"speakerBoost": 123
},
"translationTimeSkips": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
targetLanguage: '<string>',
originalLanguage: '<string>',
projectName: '<string>',
webhookUrl: '<string>',
numberOfSpeakers: '<string>',
brandVocabulary: '<string>',
removeFillerWords: true,
sourceSrt: '<string>',
keepBackgroundMusic: true,
keepOriginalVoice: true,
originalVoiceVolume: 123,
voiceIsolatorOption: '<string>',
subtitles: true,
subtitlesSource: '<string>',
lipSyncMode: '<string>',
activeSpeakerDetectionEnabled: true,
lipsyncPro: true,
voiceMode: '<string>',
voiceId: '<string>',
voiceCloningSettings: {stability: 123, similarity: 123, speakerBoost: 123},
translationTimeSkips: '<string>'
})
};
fetch('https://api.voicecheap.ai/v1/translate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.voicecheap.ai/v1/translate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'targetLanguage' => '<string>',
'originalLanguage' => '<string>',
'projectName' => '<string>',
'webhookUrl' => '<string>',
'numberOfSpeakers' => '<string>',
'brandVocabulary' => '<string>',
'removeFillerWords' => true,
'sourceSrt' => '<string>',
'keepBackgroundMusic' => true,
'keepOriginalVoice' => true,
'originalVoiceVolume' => 123,
'voiceIsolatorOption' => '<string>',
'subtitles' => true,
'subtitlesSource' => '<string>',
'lipSyncMode' => '<string>',
'activeSpeakerDetectionEnabled' => true,
'lipsyncPro' => true,
'voiceMode' => '<string>',
'voiceId' => '<string>',
'voiceCloningSettings' => [
'stability' => 123,
'similarity' => 123,
'speakerBoost' => 123
],
'translationTimeSkips' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.voicecheap.ai/v1/translate"
payload := strings.NewReader("{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.voicecheap.ai/v1/translate")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.voicecheap.ai/v1/translate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"targetLanguage\": \"<string>\",\n \"originalLanguage\": \"<string>\",\n \"projectName\": \"<string>\",\n \"webhookUrl\": \"<string>\",\n \"numberOfSpeakers\": \"<string>\",\n \"brandVocabulary\": \"<string>\",\n \"removeFillerWords\": true,\n \"sourceSrt\": \"<string>\",\n \"keepBackgroundMusic\": true,\n \"keepOriginalVoice\": true,\n \"originalVoiceVolume\": 123,\n \"voiceIsolatorOption\": \"<string>\",\n \"subtitles\": true,\n \"subtitlesSource\": \"<string>\",\n \"lipSyncMode\": \"<string>\",\n \"activeSpeakerDetectionEnabled\": true,\n \"lipsyncPro\": true,\n \"voiceMode\": \"<string>\",\n \"voiceId\": \"<string>\",\n \"voiceCloningSettings\": {\n \"stability\": 123,\n \"similarity\": 123,\n \"speakerBoost\": 123\n },\n \"translationTimeSkips\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"projectId": "<string>",
"estimatedDuration": 123
}Start Translation
Create a new translation project by uploading a video or audio file. The translation process runs asynchronously in the background. Use the status endpoint to track progress and retrieve results. Use Get Project Details when you need translated version history or lip-sync history.Concurrency Limit
You can run up to 10 translations at the same time per account. If 10 translations are already in progress, new requests returnCONCURRENT_TRANSLATION_LIMIT_REACHED (HTTP 429).
Request
This endpoint acceptsmultipart/form-data with a file upload.
Headers
string
required
Your VoiceCheap API key. Get one from app.voicecheap.ai/page-api.
Body Parameters
file
required
The video or audio file to translate.Supported video formats:
video/mp4, video/quicktime, video/x-matroska, video/webm, video/mpegSupported audio formats: audio/mpeg, audio/wav, audio/mp4, audio/x-m4a, audio/flac, audio/ogg, audio/aac, audio/webmMaximum file size by plan: Beginner 5 GB, Starter 10 GB, Creator 20 GB, Pro 30 GB, Scale 40 GB, and Enterprise 60 GB.string
required
The language to translate the content into. Must be lowercase.Allowed values (70+):
afrikaans, albanian, amharic, arabic, armenian, assamese, azerbaijani, basque, belarusian, bengali, bosnian, bulgarian, catalan, croatian, czech, danish, dutch, english, british english, estonian, finnish, french, french canadian, galician, german, greek, gujarati, hebrew, hindi, hungarian, icelandic, indonesian, irish, italian, japanese, kannada, kazakh, khmer, korean, lao, latvian, lithuanian, macedonian, malay, malayalam, mandarin, marathi, mongolian, nepali, norwegian, persian, polish, portuguese, brazilian portuguese, punjabi, romanian, russian, serbian, slovak, slovenian, spanish, swahili, swedish, tagalog, tamil, telugu, thai, turkish, ukrainian, urdu, vietnamese, welsh, yoruba, zulustring
The source language of the content using ISO language codes (e.g., Default:
en, es, fr, de, ja, zh).Strongly recommended: Leave this empty for auto-detection.Only provide this parameter if you are 100% certain the language code is correct and in valid ISO format. Incorrect language codes will cause transcription failures. Our auto-detection supports 80+ languages and is highly accurate.
auto-detectstring
A custom name for the project. Useful for identifying projects in your dashboard.Default: The project ID will be used if not provided.
string
An https endpoint that receives the webhook events for this project,
overriding the endpoint configured on your account.Default: The account webhook endpoint, when one is configured.
string
auto-detect or an integer from 1 through 32. A known speaker count can improve diarization.Default: auto-detectstring
A JSON string array of request-specific names, brands, acronyms, or specialist terms. These terms are merged with saved account or team vocabulary.
boolean
Remove common filler words from the source transcript before translation.Default:
truestring
An existing source-language SRT transcript.
originalLanguage must be explicit when this field is supplied.boolean
Whether to preserve background audio in the output.When enabled, keeps background music, ambience, laughs, claps, and crowd sounds while removing only the original voice (stem separation). Turn off if your source has no background audio.Default:
trueboolean
Keep the original speaker quietly underneath the translated voice.Default:
falsenumber
Original-voice volume from
1 through 70 when keepOriginalVoice is enabled.Default: 30string
Voice isolation mode when
Allowed values:
keepBackgroundMusic is enabled. Controls the quality and characteristics of voice separation.Studio (Recommended)
Studio (Recommended)
Our default voice processing, designed for professional audio quality:
- Removes echoes and reverberations
- Cleans technical imperfections
- Produces a clear and crisp voice
Realistic
Realistic
Preserves the natural characteristics of the recording environment:
- Maintains a sound closer to the original recording
- Preserves environmental characteristics
This option may create artifacts or unexpected effects in some cases due to the preservation of background elements.
studio, realisticDefault: studioboolean
Whether to generate subtitles for the translated video.When enabled, adds clean Netflix-style black and white subtitles. Use
subtitlesSource to choose original (source language) or translated (target language) text. Subtitles are automatically synced for optimal readability.Note: Burned-in subtitles require FFmpeg with the subtitles filter (libass). If unavailable, the API falls back to embedding a subtitle track instead of hard-burned styling.Default: falsestring
Choose the subtitle text source when
subtitles is enabled.Allowed values: translated, originalDefault: translatedNote: If original is selected but the original transcription is unavailable, subtitles fall back to translated.string
Trigger lip-sync processing after translation completes.
standard= Lip Syncpro= Lip Sync Prostudio= Lip Sync Studio
boolean
Enable active-speaker detection for the requested lip-sync run.Default:
falseboolean
Legacy lip-sync selector retained for backward compatibility.Default: not enabled (omit the field to skip lip-sync)Form-data: Send boolean values as
false= Standard lip-sync (4 minutes of credits per 1 minute of video)true= Lip Sync Pro (9 minutes of credits per 1 minute of video)
Max duration: 180 minutes per video.Latency: Lip-sync processing typically adds 2x-4x the original video duration.
Lip-sync completion and failure emails are not sent for API-triggered requests. Use the status endpoint to
track progress.
true or false strings (e.g., -F "lipsyncPro=false").Do not combine
lipsyncPro with a conflicting lipSyncMode.string
Voice strategy:
cloning or custom.Default: cloningstring
Required when
voiceMode is custom. The voice must belong to the effective project owner. Arbitrary or unowned voice IDs are rejected.object
Fine-tune voice cloning parameters for advanced control over the generated voice. Pass as a JSON string when using form-data. All values must be between 0 and 1 (with step of 0.01).
Default values (balanced):Recommended for avoiding accent reproduction:
These settings apply only when
voiceMode is cloning.Show voiceCloningSettings properties
Show voiceCloningSettings properties
number
default:"0.60"
Voice Stability (0.00 - 1.00)Determines how stable the voice is and the randomness between each generation.
- Lower values allow a wider emotional range but may cause odd or rushed speech
- Higher values produce more consistent output but may sound monotone
0.60Tip: For avoiding accent reproduction, use 0.80number
default:"0.85"
Voice Similarity (0.00 - 1.00)Controls how closely the AI adheres to the original voice.
- Higher values make the cloned voice more similar to the original
- If the original audio is noisy and similarity is too high, artifacts or background noise may carry into the generated voice
0.85Tip: For avoiding accent reproduction, use 0.20number
default:"0.30"
Speaker Boost (0.00 - 1.00)Boosts similarity to the original speaker. This is a subtle enhancement that increases resemblance to the source voice.Note: Higher values increase compute time and latency.Default:
0.30Tip: For avoiding accent reproduction, use 0.00{
"stability": 0.6,
"similarity": 0.85,
"speakerBoost": 0.3
}
{
"stability": 0.8,
"similarity": 0.2,
"speakerBoost": 0.0
}
string
A JSON array of source-time ranges that should remain in the original language.Time skips require video input and
[
{ "startTime": 10.2, "endTime": 12.8 }
]
keepBackgroundMusic=true. They cannot be combined with keepOriginalVoice and cannot overlap transcript segments.Response
boolean
required
Always
true for successful requestsstring
required
A human-readable message describing the result
string
required
The unique identifier for the created translation project. Use this ID to check status.
number
required
Rough processing estimate in minutes. The current estimate is five minutes of processing per started minute of source media.
Examples
Saved glossary rules and custom translation instructions from the effective account or team are applied automatically.
curl -X POST https://api.voicecheap.ai/v1/translate \
-H "x-api-key: vc_your-api-key" \
-F "file=@video.mp4" \
-F "targetLanguage=spanish" \
-F "projectName=My Spanish Translation" \
-F "numberOfSpeakers=2" \
-F 'brandVocabulary=["VoiceCheap","SmartSync"]' \
-F "removeFillerWords=true" \
-F "keepBackgroundMusic=true" \
-F "keepOriginalVoice=false" \
-F "voiceIsolatorOption=studio" \
-F "subtitles=true" \
-F "subtitlesSource=translated" \
-F "lipSyncMode=standard" \
-F "activeSpeakerDetectionEnabled=true"
interface StartTranslationResponse {
success: boolean;
message: string;
projectId: string;
estimatedDuration: number;
}
interface VoiceCloningSettings {
stability: number; // 0.00 - 1.00
similarity: number; // 0.00 - 1.00
speakerBoost: number; // 0.00 - 1.00
}
interface StartTranslationRequest {
targetLanguage: string;
originalLanguage?: string;
projectName?: string;
numberOfSpeakers?: 'auto-detect' | string;
brandVocabulary?: string[];
removeFillerWords?: boolean;
keepBackgroundMusic?: boolean;
keepOriginalVoice?: boolean;
originalVoiceVolume?: number;
voiceMode?: 'cloning' | 'custom';
voiceId?: string;
voiceIsolatorOption?: 'studio' | 'realistic';
subtitles?: boolean;
subtitlesSource?: 'translated' | 'original';
lipSyncMode?: 'standard' | 'pro' | 'studio';
activeSpeakerDetectionEnabled?: boolean;
voiceCloningSettings?: VoiceCloningSettings;
translationTimeSkips?: Array<{ startTime: number; endTime: number }>;
}
async function startTranslation(
file: File,
targetLanguage: string,
options?: {
originalLanguage?: string;
projectName?: string;
numberOfSpeakers?: 'auto-detect' | string;
brandVocabulary?: string[];
removeFillerWords?: boolean;
keepBackgroundMusic?: boolean;
keepOriginalVoice?: boolean;
originalVoiceVolume?: number;
voiceMode?: 'cloning' | 'custom';
voiceId?: string;
voiceIsolatorOption?: 'studio' | 'realistic';
subtitles?: boolean;
subtitlesSource?: 'translated' | 'original';
lipSyncMode?: 'standard' | 'pro' | 'studio';
activeSpeakerDetectionEnabled?: boolean;
voiceCloningSettings?: VoiceCloningSettings;
translationTimeSkips?: Array<{ startTime: number; endTime: number }>;
},
): Promise<StartTranslationResponse> {
const formData = new FormData();
formData.append('file', file);
formData.append('targetLanguage', targetLanguage);
if (options?.projectName) {
formData.append('projectName', options.projectName);
}
if (options?.originalLanguage) {
formData.append('originalLanguage', options.originalLanguage);
}
if (options?.numberOfSpeakers) {
formData.append('numberOfSpeakers', options.numberOfSpeakers);
}
if (options?.brandVocabulary) {
formData.append('brandVocabulary', JSON.stringify(options.brandVocabulary));
}
if (options?.removeFillerWords !== undefined) {
formData.append('removeFillerWords', String(options.removeFillerWords));
}
if (options?.keepBackgroundMusic !== undefined) {
formData.append('keepBackgroundMusic', String(options.keepBackgroundMusic));
}
if (options?.keepOriginalVoice !== undefined) {
formData.append('keepOriginalVoice', String(options.keepOriginalVoice));
}
if (options?.originalVoiceVolume !== undefined) {
formData.append('originalVoiceVolume', String(options.originalVoiceVolume));
}
if (options?.voiceMode) {
formData.append('voiceMode', options.voiceMode);
}
if (options?.voiceId) {
formData.append('voiceId', options.voiceId);
}
if (options?.voiceIsolatorOption) {
formData.append('voiceIsolatorOption', options.voiceIsolatorOption);
}
if (options?.subtitles !== undefined) {
formData.append('subtitles', String(options.subtitles));
}
if (options?.subtitlesSource) {
formData.append('subtitlesSource', options.subtitlesSource);
}
if (options?.lipSyncMode) {
formData.append('lipSyncMode', options.lipSyncMode);
}
if (options?.activeSpeakerDetectionEnabled !== undefined) {
formData.append('activeSpeakerDetectionEnabled', String(options.activeSpeakerDetectionEnabled));
}
if (options?.voiceCloningSettings) {
formData.append('voiceCloningSettings', JSON.stringify(options.voiceCloningSettings));
}
if (options?.translationTimeSkips) {
formData.append('translationTimeSkips', JSON.stringify(options.translationTimeSkips));
}
const response = await fetch('https://api.voicecheap.ai/v1/translate', {
method: 'POST',
headers: {
'x-api-key': 'vc_your-api-key',
},
body: formData,
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Translation failed');
}
return response.json();
}
// Usage example
const file = document.querySelector<HTMLInputElement>('#fileInput')?.files?.[0];
if (file) {
const result = await startTranslation(file, 'spanish', {
projectName: 'My Spanish Translation',
keepBackgroundMusic: true,
voiceIsolatorOption: 'studio',
subtitles: true,
subtitlesSource: 'translated',
voiceCloningSettings: {
stability: 0.6,
similarity: 0.85,
speakerBoost: 0.3,
},
});
console.log('Project ID:', result.projectId);
}
const formData = new FormData();
formData.append('file', videoFile);
formData.append('targetLanguage', 'spanish');
formData.append('projectName', 'My Spanish Translation');
formData.append('keepBackgroundMusic', 'true');
formData.append('voiceIsolatorOption', 'studio');
formData.append('subtitles', 'true');
formData.append('subtitlesSource', 'translated');
formData.append(
'voiceCloningSettings',
JSON.stringify({
stability: 0.6,
similarity: 0.85,
speakerBoost: 0.3,
}),
);
const response = await fetch('https://api.voicecheap.ai/v1/translate', {
method: 'POST',
headers: {
'x-api-key': 'vc_your-api-key',
},
body: formData,
});
const data = await response.json();
console.log('Project ID:', data.projectId);
import requests
import json
files = {'file': open('video.mp4', 'rb')}
data = {
'targetLanguage': 'spanish',
'projectName': 'My Spanish Translation',
'keepBackgroundMusic': 'true',
'voiceIsolatorOption': 'studio',
'subtitles': 'true',
'subtitlesSource': 'translated',
'voiceCloningSettings': json.dumps({
'stability': 0.60,
'similarity': 0.85,
'speakerBoost': 0.30
})
}
headers = {'x-api-key': 'vc_your-api-key'}
response = requests.post(
'https://api.voicecheap.ai/v1/translate',
headers=headers,
files=files,
data=data
)
result = response.json()
print(f"Project ID: {result['projectId']}")
<?php
$curl = curl_init();
$voiceCloningSettings = json_encode([
'stability' => 0.60,
'similarity' => 0.85,
'speakerBoost' => 0.30
]);
$postFields = [
'file' => new CURLFile('video.mp4'),
'targetLanguage' => 'spanish',
'projectName' => 'My Spanish Translation',
'keepBackgroundMusic' => 'true',
'voiceIsolatorOption' => 'studio',
'subtitles' => 'true',
'subtitlesSource' => 'translated',
'voiceCloningSettings' => $voiceCloningSettings
];
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.voicecheap.ai/v1/translate',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
CURLOPT_HTTPHEADER => [
'x-api-key: vc_your-api-key'
]
]);
$response = curl_exec($curl);
$result = json_decode($response, true);
echo "Project ID: " . $result['projectId'];
Response Example
{
"success": true,
"message": "Translation started successfully. Use the status endpoint to track progress.",
"projectId": "abc123-def456-ghi789",
"estimatedDuration": 15
}
Errors
| Status | Code | Description |
|---|---|---|
| 400 | FILE_REQUIRED | No file was uploaded with the request |
| 400 | INVALID_FILE_TYPE | The uploaded file type is not supported |
| 400 | DURATION_DETECTION_FAILED | Could not detect the duration of the uploaded file |
| 400 | INVALID_MULTIPART_REQUEST | Multipart form data is malformed or exceeds field limits |
| 400 | INVALID_BOOLEAN_VALUE | A boolean parameter has an invalid value (use “true” or “false”) |
| 400 | INVALID_JSON_FORMAT | The voiceCloningSettings JSON is malformed |
| 400 | INVALID_BRAND_VOCABULARY | A request-specific vocabulary entry is invalid |
| 400 | INVALID_SOURCE_SRT | The supplied source SRT is malformed |
| 400 | SOURCE_LANGUAGE_REQUIRED_FOR_SRT | sourceSrt requires an explicit originalLanguage |
| 400 | VOICE_ID_REQUIRED | Custom voice mode was selected without a voice ID |
| 400 | VOICE_ID_NOT_ALLOWED_WITH_CLONING | A voice ID was combined with voice cloning |
| 400 | VOICE_CLONING_SETTINGS_NOT_ALLOWED | Clone settings were combined with custom voice mode |
| 400 | CONFLICTING_LIPSYNC_OPTIONS | lipSyncMode conflicts with legacy lipsyncPro |
| 400 | TRANSLATION_TIME_SKIP_CONFLICT | Time skips conflict with another audio option |
| 400 | TRANSLATION_TIME_SKIP_REQUIRES_BACKGROUND | Time skips require background audio |
| 400 | TRANSLATION_TIME_SKIP_OUT_OF_RANGE | A time skip extends beyond the media duration |
| 400 | INVALID_TRANSLATION_TIME_SKIPS | A time skip overlaps a transcription segment |
| 400 | SUBTITLES_NOT_AVAILABLE_FOR_AUDIO | Burned-in subtitles were requested for audio input |
| 400 | LIPSYNC_NOT_AVAILABLE_FOR_AUDIO | Lip sync was requested for audio input |
| 400 | TRANSLATION_TIME_SKIP_NOT_AVAILABLE_FOR_AUDIO | Time skips were requested for audio input |
| 400 | LIPSYNC_VIDEO_TOO_LONG | Lip-sync was requested for media longer than the supported duration |
| 413 | FILE_TOO_LARGE | The uploaded file exceeds the user’s plan limit |
| 401 | MISSING_API_KEY | API key is required |
| 401 | INVALID_API_KEY_FORMAT | API key must start with vc_ |
| 401 | INVALID_API_KEY | The provided API key is invalid |
| 403 | API_ACCESS_REQUIRED | API access is required for this account |
| 403 | SUBSCRIPTION_REQUIRED | API access requires a paid subscription |
| 403 | INSUFFICIENT_CREDITS | Not enough credits to process this file |
| 403 | CUSTOM_VOICE_ACCESS_DENIED | The custom voice is not owned by the effective project owner |
| 403 | LIPSYNC_MODE_ACCESS_DENIED | The premium lip-sync mode is unavailable on the current plan |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests (limit: 10 requests per minute) |
| 429 | CONCURRENT_TRANSLATION_LIMIT_REACHED | Too many translations in progress (limit: 10 concurrent translations) |
Was this page helpful?

