Developer API
Build voice cloning and dubbing experiences with the OrangeClone API
Contents Overview
The OrangeClone API enables you to integrate professional-quality
voice cloning and video dubbing into your applications. Our AI-powered
platform supports:
Characters - Create and manage voice profiles with audio
samples
Voice Cloning - Generate realistic audio using cloned
voices
Script Generation - AI-powered script writing
Video Dubbing - Transcribe, translate, and dub videos
in 15+ languages
Base URL https://orangeclone.web.app/api Authentication
All API requests require an API key for authentication. Include your
API key in the Authorization header.
Authorization : Bearer YOUR_API_KEY
Content-Type : application/json headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
} 🔑 Getting Your API Key Log in to your OrangeClone account
Go to your Dashboard Find the "Developer API Key" section Click "Generate API Key" to create your key Copy the key and use it in your API requests Note: API keys are valid until revoked. Store them securely.
All users with credits can use the API.
Characters API
Before you can clone voices, you need to create characters with voice
samples. Characters are voice profiles that store the audio sample
used for cloning.
Create Character POST /api/characters/create
Create a new character with a voice sample. Uses multipart form data.
Form Data Parameters Parameter Type Required Description name string Yes Character name (2-50 characters) avatarStyle string Yes Avatar style (e.g., "adventurer", "avataaars", "bottts") voiceFile File Yes Audio file with voice sample (WAV, MP3, M4A - min 3 seconds)
Example const formData = new FormData ();
formData. append ( 'name' , 'Alex Voice' );
formData. append ( 'avatarStyle' , 'adventurer' );
formData. append ( 'voiceFile' , audioFile); // Audio file input
const response = await fetch ( 'https://orangeclone.web.app/api/characters/create' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY'
// Note: Don't set Content-Type, browser will set it with boundary
},
body: formData
});
const { characterId } = await response. json ();
console. log ( 'Created character:' , characterId); import requests
url = "https://orangeclone.web.app/api/characters/create"
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
# Data and Files
data = {
"name" : "Alex Voice" ,
"avatarStyle" : "adventurer"
}
files = {
"voiceFile" : open ( "your_audio.wav" , "rb" )
}
response = requests.post(url, headers = headers, data = data, files = files)
print ( f "Created character: { response.json()[ 'characterId' ] } " ) Response {
"success": "true",
"characterId": "abc123xyz"
} Delete Character DELETE /api/characters/delete
const response = await fetch ( 'https://orangeclone.web.app/api/characters/delete' , {
method: 'DELETE' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
characterId: 'abc123xyz'
})
}); import requests
url = "https://orangeclone.web.app/api/characters/delete"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
response = requests.delete(url, headers = headers, json = {
"characterId" : "abc123xyz"
}) Get Character GET /api/characters/[id]
Retrieve details of a specific character.
Update Character Details PUT /api/characters/[id]
Update character metadata like name or avatar style.
const response = await fetch ( 'https://orangeclone.web.app/api/characters/abc123xyz' , {
method: 'PUT' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
name: 'New Name' ,
avatarStyle: 'bottts'
})
}); import requests
url = "https://orangeclone.web.app/api/characters/abc123xyz"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
response = requests.put(url, headers = headers, json = {
"name" : "New Name" ,
"avatarStyle" : "bottts"
}) Update Character Voice POST /api/characters/[id]/audio
Update the voice sample for an existing character. Uploads a new audio
file.
const formData = new FormData ();
formData. append ( 'voiceFile' , newAudioFile);
const response = await fetch ( 'https://orangeclone.web.app/api/characters/abc123xyz/audio' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY'
},
body: formData
}); import requests
url = "https://orangeclone.web.app/api/characters/abc123xyz/audio"
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
files = { "voiceFile" : open ( "new_sample.wav" , "rb" )}
response = requests.post(url, headers = headers, files = files) Voice Cloning API
Generate audio using cloned character voices for single or
multi-speaker dialogue.
POST /api/voices_clone
Request Body Parameter Type Required Description text string Yes Text to synthesize. For dialogue, use "Speaker 1: text" format. character_ids string[] Yes Array of character IDs to use for voice cloning.
Example: Single Voice const response = await fetch ( 'https://orangeclone.web.app/api/voices_clone' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
text: "Hello, this is my cloned voice!" ,
character_ids: [ "abc123xyz" ] // Your character ID from create step
})
});
const { data } = await response. json ();
console. log ( 'Job ID:' , data.jobId); // Use to track progress import requests
url = "https://orangeclone.web.app/api/voices_clone"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"text" : "Hello, this is my cloned voice!" ,
"character_ids" : [ "abc123xyz" ]
}
response = requests.post(url, headers = headers, json = payload)
print ( f "Job ID: { response.json()[ 'data' ][ 'jobId' ] } " ) Example: Multi-Speaker Dialogue const response = await fetch ( 'https://orangeclone.web.app/api/voices_clone' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
text: "Speaker 1: Hello, how are you? \n Speaker 2: I'm doing great, thanks for asking! \n Speaker 1: That's wonderful to hear." ,
character_ids: [ "char_abc123" , "char_def456" ]
})
}); import requests
url = "https://orangeclone.web.app/api/voices_clone"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
text = """Speaker 1: Hello, how are you?
Speaker 2: I'm doing great, thanks for asking!
Speaker 1: That's wonderful to hear."""
payload = {
"text" : text,
"character_ids" : [ "char_abc123" , "char_def456" ]
}
# Cost is estimated based on the total length of the dialogue
response = requests.post(url, headers = headers, json = payload) Response {
"success": true,
"data": {
"jobId": "job_xyz789",
"status": "queued",
"speakerCount": 2,
"estimatedCost": 2
}
} Step 4: Track Job Status Voice cloning is asynchronous. Use the Job ID to check status:
GET /api/voices/[jobId]
Status Description queued Job is waiting to be processed. processing AI is currently generating the audio. completed Audio generated successfully. audioUrl will be present. failed An error occurred. Check the error field for details.
const jobId = 'job_xyz789' ;
const checkStatus = async () => {
const response = await fetch ( "https://orangeclone.web.app/api/voices/" + jobId, {
headers: { 'Authorization' : 'Bearer YOUR_API_KEY' }
});
const { data } = await response. json ();
if (data.status === 'completed' ) {
console. log ( 'Audio URL:' , data.audioUrl);
} else if (data.status === 'failed' ) {
console. error ( 'Error:' , data.error);
} else {
// Check again in a few seconds
setTimeout (checkStatus, 3000 );
}
};
checkStatus (); import time
import requests
job_id = "job_xyz789"
url = f "https://orangeclone.web.app/api/voices/ { job_id } "
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
while True :
response = requests.get(url, headers = headers)
data = response.json().get( "data" , {})
status = data.get( "status" )
if status == "completed" :
print ( f "Audio URL: { data.get( 'audioUrl' ) } " )
break
elif status == "failed" :
print ( f "Error: { data.get( 'error' ) } " )
break
time.sleep( 3 ) Batch Processing API
Process multiple audio generation jobs in a single request. This is
ideal for generating voiceovers for entire stories or multi-scene videos
at once.
POST /api/batch_tts
Request Body Parameter Type Required Description storyId string Yes A unique identifier for the story or project. scenes array Yes Array of scene objects (see below). callbackUrl string No URL to receive POST notification when all jobs are complete
(optional).
Scene Object Property Type Description index number Sequential index of the scene (starts at 0). text string The script text for this scene. characterId string The ID of the character voice to use.
Example const response = await fetch ( 'https://orangeclone.web.app/api/batch_tts' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
storyId: "story_123" ,
scenes: [
{ index: 0 , text: "Welcome to our story!" , characterId: "char_1" },
{ index: 1 , text: "Today we explore the ocean." , characterId: "char_2" }
]
})
});
const { success , data } = await response. json ();
console. log ( 'Batch Job ID:' , data.batchJobId); import requests
url = "https://orangeclone.web.app/api/batch_tts"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"storyId" : "story_123" ,
"scenes" : [
{ "index" : 0 , "text" : "Welcome to our story!" , "characterId" : "char_1" },
{ "index" : 1 , "text" : "Today we explore the ocean." , "characterId" : "char_2" }
]
}
response = requests.post(url, headers = headers, json = payload)
print ( "Batch Job ID: " + response.json()[ "data" ][ "batchJobId" ]) Check Batch Status Get the progress and audio URLs for all scenes in a batch.
GET /api/batch_tts_status?batchJobId=[id]
const batchJobId = 'abc-123-xyz' ;
const response = await fetch ( 'https://orangeclone.web.app/api/batch_tts_status?batchJobId=' + batchJobId, {
headers: { 'Authorization' : 'Bearer YOUR_API_KEY' }
});
const data = await response. json ();
console. log ( 'Overall Status:' , data.status);
console. log ( 'Scenes:' , data.scenes); // Array with audioUrl for completed scenes import requests
batch_job_id = "abc-123-xyz"
url = "https://orangeclone.web.app/api/batch_tts_status?batchJobId=" + batch_job_id
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
response = requests.get(url, headers = headers)
data = response.json()
print ( "Status: " + str (data.get( "status" )))
for scene in data.get( "scenes" , []):
if scene.get( "status" ) == "completed" :
print ( "Scene " + str (scene.get( "sceneIndex" )) + ": " + str (scene.get( "audioUrl" ))) Script Generation API Generate AI-written scripts for voice content.
POST /api/scripts_generate
Request Body Parameter Type Required Description mode string Yes "single" for monologue, "dialogue" for conversation template string No youtube_ad, podcast_intro, tutorial, storytelling, sales_pitch,
interview, comedy, motivational context string Yes Context or prompt for the script (max 2000 chars) characters array Yes Array of character objects with id and name tone string No Professional, Casual, Humorous, Dramatic, etc. length string No "Short (<30s)", "Medium (1-2m)", or "Long (3m+)"
Example const response = await fetch ( 'https://orangeclone.web.app/api/scripts_generate' , {
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
mode: 'dialogue' ,
template: 'podcast_intro' ,
context: 'A tech podcast discussing the future of AI' ,
characters: [
{ id: '1' , name: 'Alex' },
{ id: '2' , name: 'Jordan' }
],
tone: 'Professional' ,
length: 'Medium (1-2m)'
})
});
const { script , generationId } = await response. json ();
console. log (script); import requests
url = "https://orangeclone.web.app/api/scripts_generate"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
payload = {
"mode" : "dialogue" ,
"template" : "podcast_intro" ,
"context" : "A tech podcast discussing the future of AI" ,
"characters" : [
{ "id" : "1" , "name" : "Alex" },
{ "id" : "2" , "name" : "Jordan" }
],
"tone" : "Professional" ,
"length" : "Medium (1-2m)"
}
response = requests.post(url, headers = headers, json = payload)
print (response.json()[ "script" ]) Dubbing Pipeline API
The dubbing pipeline consists of three steps: transcription,
translation, and voice cloning. Each step is a separate API call for
full control over the process.
Step 1: Transcribe POST /api/dubbing_transcribe
Upload media and start speech-to-text transcription.
// First, get an upload URL
const uploadResponse = await fetch (
'https://orangeclone.web.app/api/dubbing_transcribe?action=get_upload_url' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
fileName: 'video.mp4' ,
contentType: 'video/mp4'
})
}
);
const { data : { uploadUrl , mediaPath } } = await uploadResponse. json ();
// Upload the file directly to the signed URL
await fetch (uploadUrl, {
method: 'PUT' ,
body: videoFile,
headers: { 'Content-Type' : 'video/mp4' }
});
// Start transcription
const transcribeResponse = await fetch (
'https://orangeclone.web.app/api/dubbing_transcribe' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
mediaPath,
mediaType: 'video' ,
duration: 120 ,
fileSizeMB: 50
})
}
);
const { data : { jobId } } = await transcribeResponse. json (); import requests
API_URL = "https://orangeclone.web.app/api"
HEADERS = { "Authorization" : "Bearer YOUR_API_KEY" }
# 1. Get Upload URL
resp = requests.post( f " { API_URL } /dubbing_transcribe?action=get_upload_url" , headers = HEADERS , json = {
"fileName" : "video.mp4" ,
"contentType" : "video/mp4"
})
data = resp.json()[ "data" ]
upload_url = data[ "uploadUrl" ]
media_path = data[ "mediaPath" ]
# 2. Upload File
with open ( "video.mp4" , "rb" ) as f:
requests.put(upload_url, data = f, headers = { "Content-Type" : "video/mp4" })
# 3. Start Transcription
resp = requests.post( f " { API_URL } /dubbing_transcribe" , headers = HEADERS , json = {
"mediaPath" : media_path,
"mediaType" : "video" ,
"duration" : 120 ,
"fileSizeMB" : 50
})
job_id = resp.json()[ "data" ][ "jobId" ] Step 2: Translate (Optional) POST /api/dubbing_translate
Translate the transcript to a target language. If you want to keep the
original language but use cloned voices, you can skip this step.
Supported Languages 🇺🇸 English (en) 🇪🇸 Spanish (es) 🇫🇷 French (fr) 🇩🇪 German (de) 🇮🇹 Italian (it) 🇵🇹 Portuguese (pt) 🇷🇺 Russian (ru) 🇯🇵 Japanese (ja) 🇰🇷 Korean (ko) 🇨🇳 Chinese (zh) 🇸🇦 Arabic (ar) 🇮🇳 Hindi (hi) 🇳🇱 Dutch (nl) 🇵🇱 Polish (pl) 🇹🇷 Turkish (tr)
💡 Pro Tip
You can also translate only specific segments of your media by using
the /api/dubbing_segments endpoint (beta).
Step 3: Update Settings & Voice Mapping PUT /api/dubbing/[jobId]
Configure voice mapping, translation mode, and target language for your
job. This is where you assign your characters to detected speakers.
Request Body Parameters Parameter Type Description targetLanguage string ISO code (e.g., "es", "fr"). Use "" for original. translateAll boolean Set true to translate the entire transcript. voiceMapping object Map speakerId to character profiles (see below).
Voice Mapping Object {
"speaker_1" : {
"type" : "character" ,
"characterId" : "abc123xyz"
},
"speaker_2" : {
"type" : "original"
}
} Step 4: Clone & Dub POST /api/dubbing_clone
Apply voice cloning to create the dubbed audio track using the settings
provided in Step 3.
const cloneResponse = await fetch (
'https://orangeclone.web.app/api/dubbing_clone' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer YOUR_API_KEY' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
jobId: 'job_xyz789'
})
}
); import requests
url = "https://orangeclone.web.app/api/dubbing_clone"
headers = {
"Authorization" : "Bearer YOUR_API_KEY" ,
"Content-Type" : "application/json"
}
response = requests.post(url, headers = headers, json = {
"jobId" : "job_xyz789"
}) Step 5: Track Job Status GET /api/dubbing/[jobId]
Track the progress of your dubbing job.
Status Description transcribing Job is currently extracting text from media. translating Transcript is being translated to target language. cloning AI is generating dubbed audio tracks. completed Dubbing pipeline finished. dubbedUrl will be present. failed An error occurred. Check the error field for details.
const response = await fetch ( 'https://orangeclone.web.app/api/dubbing/job_xyz789' , {
headers: {
'Authorization' : 'Bearer YOUR_API_KEY'
}
});
const { data } = await response. json ();
if (data.status === 'completed' ) {
console. log ( 'Dubbed URL:' , data.dubbedUrl);
} else {
console. log ( 'Status:' , data.status);
} import requests
response = requests.get(
"https://orangeclone.web.app/api/dubbing/job_xyz789" ,
headers = { "Authorization" : "Bearer YOUR_API_KEY" }
)
data = response.json()[ "data" ]
if data[ "status" ] == "completed" :
print ( f "Dubbed URL: { data[ 'dubbedUrl' ] } " )
else :
print ( f "Status: { data[ 'status' ] } " ) Pricing & Rate Limits Credit Costs Feature Cost Voice Cloning (single speaker) 1 credit per 10 seconds Voice Cloning (multi-speaker) 2 credits per 10 seconds Script Generation 1 credit Video Dubbing Based on video duration
Rate Limits Tier Requests/Minute Max Duration Free 10 2 minutes Pro 30 30 minutes Enterprise Unlimited Unlimited