{"openapi":"3.1.0","info":{"title":"VocalLab API","version":"2.0.0","description":"GenMax-compatible voice API. Change the base URL and use a VocalLab key in `xi-api-key`; paths, fields, status codes and pagination follow GenMax. Each key belongs to one VocalLab account and sees only that account’s tasks."},"servers":[{"url":"https://api.vocallab.net"}],"security":[{"XiApiKey":[]}],"tags":[{"name":"Auth"},{"name":"API Keys"},{"name":"Models"},{"name":"Languages"},{"name":"Elevenlabs Voices"},{"name":"MiniMax Voices"},{"name":"CapCut Voices"},{"name":"Text to speech"},{"name":"Dialogue"},{"name":"Speech to text"},{"name":"Voice Changer"},{"name":"Dubbing"},{"name":"VocalLab extensions"}],"components":{"securitySchemes":{"XiApiKey":{"type":"apiKey","in":"header","name":"xi-api-key"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"required":{"type":"integer"}}},"QuoteRequest":{"type":"object","required":["kind","payload"],"properties":{"kind":{"enum":["tts","dialogue","clone","voice_change","stt","dubbing","scenes","srt"]},"payload":{"type":"object"},"upload_id":{"type":"string"},"output_format":{"type":"string"}}},"TtsRequest":{"type":"object","required":["text","provider","model_id"],"properties":{"text":{"type":"string"},"provider":{"type":"string"},"model_id":{"type":"string"},"language_code":{"type":"string"},"voice_settings":{"type":"object","additionalProperties":false,"properties":{"stability":{"type":"number","minimum":0,"maximum":1},"similarity_boost":{"type":"number","minimum":0,"maximum":1},"style":{"type":"number","minimum":0,"maximum":1},"use_speaker_boost":{"type":"boolean"},"speed":{"type":"number","minimum":0.5,"maximum":2},"pitch":{"type":"number","minimum":-12,"maximum":12},"vol":{"type":"number","minimum":0,"maximum":10}}},"output_format":{"enum":["source","mp3_44100_128","mp3_44100_192","wav_8000","wav_16000","wav_22050","wav_24000","wav_44100","wav_48000"]},"quote_id":{"type":"string"},"idempotency_key":{"type":"string"}}},"DialogueSpeaker":{"type":"object","required":["provider","voice_id","model_id"],"additionalProperties":false,"properties":{"provider":{"type":"string"},"voice_id":{"type":"string"},"model_id":{"type":"string"},"language_code":{"type":"string"},"voice_settings":{"type":"object","additionalProperties":false}}},"DialogueRequest":{"type":"object","required":["text","speakers"],"additionalProperties":false,"properties":{"text":{"type":"string"},"speakers":{"type":"object","minProperties":2,"maxProperties":20,"additionalProperties":{"$ref":"#/components/schemas/DialogueSpeaker"}},"pause_between_turns":{"type":"number","minimum":0,"maximum":3},"title":{"type":"string"},"quote_id":{"type":"string"},"idempotency_key":{"type":"string"}}},"ScenePayload":{"type":"object","required":["voice_id","provider","model_id","scenes"],"additionalProperties":false,"properties":{"voice_id":{"type":"string"},"voice_name":{"type":"string"},"provider":{"enum":["elevenlabs","minimax","capcut"]},"model_id":{"type":"string"},"language_code":{"type":"string"},"voice_settings":{"type":"object"},"pauseSeconds":{"type":"number","minimum":0,"maximum":10},"scenes":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["text"],"additionalProperties":false,"properties":{"index":{"type":"integer","minimum":1},"text":{"type":"string","minLength":1,"maxLength":5000}}}}}},"SrtPayload":{"type":"object","required":["voice_id","provider","model_id","cues"],"additionalProperties":false,"properties":{"voice_id":{"type":"string"},"voice_name":{"type":"string"},"provider":{"enum":["elevenlabs","minimax","capcut"]},"model_id":{"type":"string"},"language_code":{"type":"string"},"voice_settings":{"type":"object"},"fit":{"enum":["speed"]},"cues":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["index","startMs","endMs","text"],"additionalProperties":false,"properties":{"index":{"type":"integer","minimum":1},"startMs":{"type":"integer","minimum":0},"endMs":{"type":"integer","maximum":7200000},"text":{"type":"string","minLength":1,"maxLength":5000}}}}}},"CreateTaskRequest":{"type":"object","required":["kind","payload"],"properties":{"kind":{"enum":["tts","dialogue","clone","voice_change","stt","dubbing","scenes","srt"]},"payload":{"type":"object"},"upload_id":{"type":"string"},"output_format":{"enum":["source","mp3_44100_128","mp3_44100_192","wav_8000","wav_16000","wav_22050","wav_24000","wav_44100","wav_48000"]},"quote_id":{"type":"string"},"title":{"type":"string","maxLength":120},"idempotency_key":{"type":"string","minLength":12,"maxLength":120}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string"},"audio_url":{"type":["string","null"]}},"required":["id","status"]}}},"paths":{"/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Get user, credits...","description":"Returns the account that owns the API key, including its remaining credit balance. `key` and `quota` describe the calling key and its daily request quota.","operationId":"auth.me","security":[{"XiApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"id":"550e8400-e29b-41d4-a716-446655440000","email":"user@example.com","name":"John Doe","avatar_url":null,"credit_balance":4000,"role":"user","key":{"id":"0c6b1a2e-…","prefix":"vl_live_AbCdEfGh","name":"Production"},"quota":{"dailyLimit":1000,"used":12,"remaining":988,"resetsAt":"2026-10-12T00:00:00.000Z"}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/api-keys":{"get":{"tags":["API Keys"],"summary":"Get API key","description":"Describes the calling API key. VocalLab stores only a hash of each key, so `api_key` is masked; the full key is shown once when it is created or regenerated.","operationId":"keys.get","security":[{"XiApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"api_key":"vl_live_AbCdEfGh…","id":"0c6b1a2e-…","name":"Production","created_at":"2026-10-11T07:00:00.000Z","last_used_at":"2026-10-11T08:00:00.000Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/api-keys/regenerate":{"post":{"tags":["API Keys"],"summary":"Regenerate API key","description":"Revokes the calling key immediately and returns its replacement. Store the new key; it is not shown again.","operationId":"keys.regenerate","security":[{"XiApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"api_key":"vl_live_…","message":"API key regenerated successfully"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/models":{"get":{"tags":["Models"],"summary":"Get models","description":"Text to speech models enabled on VocalLab. Defaults to ElevenLabs; pass `provider=minimax` or `provider=capcut` for other providers.","operationId":"models.list","security":[{"XiApiKey":[]}],"parameters":[{"name":"provider","in":"query","required":false,"description":"`elevenlabs` (default), `minimax` or `capcut`.","schema":{"type":"string"}}],"responses":{"200":{"description":"ElevenLabs models (default); MiniMax models (provider=minimax)","content":{"application/json":{"examples":{"first":{"summary":"ElevenLabs models (default)","value":[{"model_id":"eleven_multilingual_v2","name":"Eleven Multilingual v2","description":"","can_do_text_to_speech":true,"can_do_voice_conversion":false,"maximum_text_length_per_request":5000,"token_cost_factor":1,"model_rates":{"character_cost_multiplier":1},"languages":[{"language_id":"en","name":"English"}]}]},"example2":{"summary":"MiniMax models (provider=minimax)","value":[{"model_id":"speech-2.8-hd","name":"MiniMax Speech 2.8 HD","description":"","credit_ratio":1,"max_chars":5000}]}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/languages":{"get":{"tags":["Languages"],"summary":"Get languages","description":"Languages accepted for text to speech. ElevenLabs and CapCut use ISO codes (e.g. `vi`); MiniMax uses full names (e.g. `Vietnamese`). Either form is accepted in requests.","operationId":"languages.list","security":[{"XiApiKey":[]}],"parameters":[{"name":"provider","in":"query","required":false,"description":"`elevenlabs` (default), `minimax` or `capcut`.","schema":{"type":"string"}}],"responses":{"200":{"description":"ElevenLabs languages (default); MiniMax languages (provider=minimax)","content":{"application/json":{"examples":{"first":{"summary":"ElevenLabs languages (default)","value":[{"code":"en","name":"English"},{"code":"vi","name":"Vietnamese"}]},"example2":{"summary":"MiniMax languages (provider=minimax)","value":[{"code":"English","name":"English"},{"code":"Vietnamese","name":"Vietnamese"}]}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/default-voices":{"get":{"tags":["Elevenlabs Voices"],"summary":"List default voices","description":"ElevenLabs premade voices. `preview_url` is a short-lived signed link served by VocalLab.","operationId":"voices.default","security":[{"XiApiKey":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"description":"Voices per page.","schema":{"type":"integer","default":30}},{"name":"search","in":"query","required":false,"description":"Filter by voice name.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"voices":[{"voice_id":"rv30Fd6w5bnbL0kHzWlr","name":"Aria","description":"A young, expressive female voice.","preview_url":"https://api.vocallab.net/audio/voices/elevenlabs/rv30Fd6w5bnbL0kHzWlr.mp3?exp=1767225600&sig=…","category":"premade","gender":"female","age":"young","accent":"american","language":"en","use_case":"social_media","descriptive":"expressive","free_users_allowed":true,"verified_languages":[{"language_id":"en","language":"English","model_id":"eleven_multilingual_v2","accent":"American","locale":"en-US"}]}],"has_more":true,"last_sort_id":"next_page_token_value"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/shared-voices":{"get":{"tags":["Elevenlabs Voices"],"summary":"List shared voices","description":"The ElevenLabs shared voice library with filters and sorting.","operationId":"voices.shared","security":[{"XiApiKey":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"description":"Voices per page, max 100.","schema":{"type":"integer","default":30}},{"name":"page","in":"query","required":false,"description":"Zero-based page number.","schema":{"type":"integer","default":0}},{"name":"search","in":"query","required":false,"description":"Search name or description.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"`trending`, `created_date`, `cloned_by_count` or `usage_character_count_1y`.","schema":{"type":"string","default":"trending"}},{"name":"category","in":"query","required":false,"description":"`high_quality`, or omit for all.","schema":{"type":"string"}},{"name":"gender","in":"query","required":false,"description":"`male`, `female` or `neutral`.","schema":{"type":"string"}},{"name":"age","in":"query","required":false,"description":"`young`, `middle_aged` or `old`.","schema":{"type":"string"}},{"name":"accent","in":"query","required":false,"description":"E.g. `american`, `british`.","schema":{"type":"string"}},{"name":"required_languages","in":"query","required":false,"description":"Language code, e.g. `en`.","schema":{"type":"string"}},{"name":"use_cases[]","in":"query","required":false,"description":"Repeatable. `conversational`, `narrative_and_story`, `characters_and_animation`, `social_media`, `entertainment_and_tv`, `advertisement`, `informative_and_educational`.","schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"voices":[{"voice_id":"pNInz6obpgDQGcFmaJgB","name":"Adam","description":"A warm, friendly male voice.","preview_url":"https://api.vocallab.net/audio/voices/elevenlabs/pNInz6obpgDQGcFmaJgB.mp3?exp=1767225600&sig=…","category":"professional","gender":"male","age":"middle_aged","accent":"american","language":"en","use_case":"narration","descriptive":"warm","free_users_allowed":true,"usage_character_count_1y":1500000,"usage_character_count_7d":25000,"cloned_by_count":1200,"featured":false,"rate":0,"live_moderation_enabled":false,"date_unix":1700000000,"verified_languages":[{"language_id":"en","language":"English","model_id":"eleven_multilingual_v2","accent":"American","locale":"en-US"}],"image_url":"https://storage.googleapis.com/images/adam.jpg"}],"has_more":true,"last_sort_id":"abc123def456"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/minimax/system-voices":{"get":{"tags":["MiniMax Voices"],"summary":"List system voices","description":"The MiniMax system voice library. Use `voice_id` or `uniq_id` with Text to speech (provider `minimax`).","operationId":"minimax.system","security":[{"XiApiKey":[]}],"parameters":[{"name":"page","in":"query","required":false,"description":"One-based page number.","schema":{"type":"integer","default":1}},{"name":"page_size","in":"query","required":false,"description":"Voices per page.","schema":{"type":"integer","default":30}},{"name":"search","in":"query","required":false,"description":"Filter by name.","schema":{"type":"string"}},{"name":"gender","in":"query","required":false,"description":"E.g. `Male`, `Female`.","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"E.g. `English`, `Chinese (Mandarin)`.","schema":{"type":"string"}},{"name":"accent","in":"query","required":false,"description":"E.g. `EN-British`.","schema":{"type":"string"}},{"name":"age","in":"query","required":false,"description":"Comma-separated, e.g. `Young,Middle-aged`.","schema":{"type":"string"}},{"name":"use_cases","in":"query","required":false,"description":"Comma-separated, e.g. `Audiobook,Podcast`.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"voice_list":[{"voice_id":"226905123659939","voice_name":"Aussie Bloke","uniq_id":"English_Aussie_Bloke","tag_list":["English","Male","Young","EN-Australian"],"cover_url":"https://cdn.hailuoai.video/moss/voice_cover/xxx.webp","sample_audio":"https://api.vocallab.net/audio/voices/minimax/226905123659939.mp3?exp=1767225600&sig=…","description":"A warm Australian male voice."}],"total":150,"has_more":true}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/minimax/voices":{"get":{"tags":["MiniMax Voices"],"summary":"List cloned voices","description":"Your cloned voices with status `processing`, `done` or `failed`. Use `id` as the `voice_id` for MiniMax text to speech once the status is `done`.","operationId":"minimax.clones","security":[{"XiApiKey":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"voices":[{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","voice_name":"My Custom Voice","sample_audio_url":"https://api.vocallab.net/audio/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a.mp3?exp=1767225600&sig=…","cover_url":null,"language_tag":"English","gender":"Male","status":"done","created_at":"2026-10-11T10:30:00.000Z"},{"id":"b2c3d4e5-f6a7-8901-bcde-f12345678901","voice_name":"Processing Voice","language_tag":"English","gender":"Female","status":"processing","created_at":"2026-10-11T10:30:00.000Z"}]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/minimax/voices/clone":{"post":{"tags":["MiniMax Voices"],"summary":"Clone voice","description":"Clone a voice from an audio sample (10 s – 5 min, max 20 MB). Processing is asynchronous: poll List cloned voices until the status is `done`. Credits are reserved when the request is accepted and refunded if cloning fails.","operationId":"minimax.clone","security":[{"XiApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","voice_name"],"properties":{"file":{"type":"string","format":"binary","description":"Audio sample, max 20 MB."},"voice_name":{"type":"string","description":"Name for the cloned voice."},"language_tag":{"type":"string","description":"Language of the sample, e.g. `English`, `Vietnamese`.","default":"English"},"gender":{"type":"string","description":"`Male` or `Female`.","default":"Male"},"need_noise_reduction":{"type":"boolean","description":"Apply noise reduction to the sample.","default":true},"preview_text":{"type":"string","description":"Text for the preview sample, max 200 characters.","default":"Hello"}}}}}},"responses":{"200":{"description":"Clone accepted (processing)","content":{"application/json":{"example":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","voice_name":"My Voice","language_tag":"English","gender":"Male","status":"processing","created_at":"2026-10-11T10:30:00.000Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}}}}},"/v1/minimax/voices/{id}":{"delete":{"tags":["MiniMax Voices"],"summary":"Delete cloned voice","description":"Delete a cloned voice. It no longer appears in the list and can no longer be used.","operationId":"minimax.deleteClone","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Cloned voice ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"example":{"success":true,"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"voice not found"}}}}}}},"/v1/minimax/voices/{id}/retry":{"post":{"tags":["MiniMax Voices"],"summary":"Retry clone","description":"Re-run a failed or completed clone with the original sample and settings. Credits are charged again. The response carries the ID of the new clone.","operationId":"minimax.retryClone","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Cloned voice ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"responses":{"200":{"description":"Clone re-initiated (processing)","content":{"application/json":{"example":{"id":"c3d4e5f6-a7b8-9012-cdef-123456789012","voice_name":"My Voice","language_tag":"English","gender":"Male","status":"processing","created_at":"2026-10-11T10:30:00.000Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"voice not found"}}}},"409":{"description":"Only completed or failed tasks can be retried.","content":{"application/json":{"example":{"error":"only completed or failed tasks can be retried"}}}},"422":{"description":"The stored source file is no longer available. Nothing is charged.","content":{"application/json":{"example":{"error":"cannot retry: source file no longer available"}}}}}}},"/v1/capcut/system-voices":{"get":{"tags":["CapCut Voices"],"summary":"List system voices","description":"The CapCut voice library. Each `voice_id` can be used with Text to speech (provider `capcut`).","operationId":"capcut.system","security":[{"XiApiKey":[]}],"parameters":[{"name":"page","in":"query","required":false,"description":"One-based page number.","schema":{"type":"integer","default":1}},{"name":"page_size","in":"query","required":false,"description":"Voices per page.","schema":{"type":"integer","default":30}},{"name":"search","in":"query","required":false,"description":"Case-insensitive match on the name.","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"`en`, `vi`, `zh`, `id`, `es`, `pt`, `ja` or `th`.","schema":{"type":"string"}},{"name":"gender","in":"query","required":false,"description":"`Male`, `Female` or `Gender Diversity`.","schema":{"type":"string"}},{"name":"age","in":"query","required":false,"description":"E.g. `Elderly`, `Teenager`.","schema":{"type":"string"}},{"name":"emotion","in":"query","required":false,"description":"E.g. `Excited`, `Plain`.","schema":{"type":"string"}},{"name":"accent","in":"query","required":false,"description":"E.g. `Gentle / Kind`, `Deep`.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"voice_list":[{"voice_id":"7036989371643923969","name":"Energetic Narrator","language":"en","gender":"Male","platform":"sami","image_url":null,"tags":["male","steady","narration"],"preview_url":"https://api.vocallab.net/audio/voices/capcut/7036989371643923969.mp3?exp=1767225600&sig=…"}],"total":480,"has_more":true}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/capcut/voices/{voice_id}/preview":{"get":{"tags":["CapCut Voices"],"summary":"Preview voice","description":"Stream the audio sample of a CapCut voice.","operationId":"capcut.preview","security":[{"XiApiKey":[]}],"parameters":[{"name":"voice_id","in":"path","required":true,"description":"CapCut voice ID.","schema":{"type":"string"}}],"responses":{"200":{"description":"Audio sample (audio/mpeg)","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"Unknown voice.","content":{"application/json":{"example":{"error":"voice not found"}}}}}}},"/v1/text-to-speech/{voice_id}":{"post":{"tags":["Text to speech"],"summary":"Text to speech","description":"Convert text to speech with ElevenLabs, MiniMax or CapCut. The task runs asynchronously: poll Get history detail with the returned `id` until `status` is `completed` or `failed`. Credits are reserved upfront and the unused or failed part is refunded.","operationId":"tts.create","security":[{"XiApiKey":[]}],"parameters":[{"name":"voice_id","in":"path","required":true,"description":"ElevenLabs voice ID; MiniMax `voice_id`, `uniq_id` or cloned voice ID; or CapCut voice ID.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","language_code"],"properties":{"text":{"type":"string","description":"Text to convert."},"model_id":{"type":"string","description":"Model from Get models. For CapCut use `capcut`.","default":"eleven_multilingual_v2"},"provider":{"type":"string","description":"`elevenlabs`, `minimax` or `capcut`.","default":"elevenlabs"},"language_code":{"type":"string","description":"ISO code (ElevenLabs, CapCut) or language name (MiniMax). See Get languages."},"voice_settings":{"type":"object","properties":{"stability":{"type":"number","description":"[ElevenLabs] 0.0–1.0"},"similarity_boost":{"type":"number","description":"[ElevenLabs] 0.0–1.0"},"style":{"type":"number","description":"[ElevenLabs] 0.0–1.0"},"use_speaker_boost":{"type":"boolean","description":"[ElevenLabs] Speaker boost"},"speed":{"type":"number","description":"ElevenLabs 0.7–1.2; MiniMax and CapCut 0.5–2.0. Default 1.0."},"pitch":{"type":"integer","description":"[MiniMax, CapCut] −12 to 12. Default 0."},"vol":{"type":"number","description":"[MiniMax] 0.01–10. Default 1.0."}},"description":"Voice settings. Accepted fields depend on the provider."},"export_transcript":{"type":"boolean","description":"Also generate an SRT transcript. Adds about 15% to the credit cost.","default":false},"output_format":{"type":"string","description":"VocalLab extension: `source`, `mp3_44100_128`, `mp3_44100_192` or `wav_8000`…`wav_48000`.","default":"source"}}},"example":{"text":"Hello world","model_id":"eleven_multilingual_v2","language_code":"en","voice_settings":{"stability":0.5,"similarity_boost":0.75,"speed":1}}}}},"responses":{"202":{"description":"Accepted — the task is queued.","content":{"application/json":{"example":{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","status":"pending"}}}},"400":{"description":"Invalid request, e.g. a missing language code.","content":{"application/json":{"example":{"error":"missing_language_code"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}}}}},"/v1/history":{"get":{"tags":["Text to speech"],"summary":"Get history list","description":"Text to speech and dialogue tasks, newest first.","operationId":"tts.history","security":[{"XiApiKey":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"description":"Tasks per page, 1–100.","schema":{"type":"integer","default":30}},{"name":"page","in":"query","required":false,"description":"Zero-based page number.","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"tasks":[{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"completed","progress":100,"provider":"elevenlabs","text":"Hello world!","voice_id":"UgBBYS2sOqTuMpoF3BR0","model_id":"eleven_multilingual_v2","metadata":{"language_code":"en","voice_settings":{"stability":0.5,"similarity_boost":0.75,"style":0,"use_speaker_boost":true,"speed":1}},"result":{"audio_url":"https://api.vocallab.net/audio/9b19d3e2-7c68-4eca-be48-e9917682d73e.mp3?exp=1767225600&sig=…"},"error":null,"characters_used":12,"credits_deducted":12,"created_at":"2026-10-11T07:42:13.641Z","updated_at":"2026-10-11T07:42:16.432Z"},{"id":"id_of_another_task","user_id":"user_123","status":"completed","progress":100,"provider":"minimax","text":"Hello from MiniMax!","voice_id":"English_Aussie_Bloke","model_id":"speech-2.8-turbo","metadata":{"language_code":"English","voice_settings":{"speed":1,"pitch":0,"vol":1}},"result":{"audio_url":"https://api.vocallab.net/audio/9b19d3e2-7c68-4eca-be48-e9917682d73e.mp3?exp=1767225600&sig=…"},"error":null,"characters_used":19,"credits_deducted":19,"created_at":"2026-10-11T07:42:13.641Z","updated_at":"2026-10-11T07:42:16.432Z"}],"has_more":false}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/history/{id}":{"get":{"tags":["Text to speech"],"summary":"Get history detail","description":"One text to speech or dialogue task, for polling. `status` is `pending`, `processing`, `completed` or `failed`. `result.audio_url` is a signed link valid for 24 hours; read the task again for a fresh link.","operationId":"tts.get","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"processing","progress":60,"provider":"elevenlabs","text":"Hello world!","voice_id":"UgBBYS2sOqTuMpoF3BR0","model_id":"eleven_multilingual_v2","metadata":{"language_code":"en","voice_settings":{"stability":0.5,"similarity_boost":0.75,"style":0,"use_speaker_boost":true,"speed":1}},"result":{"audio_url":null},"error":null,"characters_used":12,"credits_deducted":12,"created_at":"2026-10-11T07:42:13.641Z","updated_at":"2026-10-11T07:42:16.432Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}}}},"delete":{"tags":["Text to speech"],"summary":"Delete history","description":"Delete a finished text to speech or dialogue task and its files.","operationId":"tts.delete","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"message":"deleted"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"The task is still pending or processing.","content":{"application/json":{"example":{"error":"task_still_running","message":"This task is still running. Wait for it to finish before deleting it."}}}}}}},"/v1/history/{id}/retry":{"post":{"tags":["Text to speech"],"summary":"Retry task","description":"Re-run a completed or failed text to speech, dialogue or SRT task with its original text and settings. Credits are charged again. Poll the new task `id` that is returned.","operationId":"tts.retry","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"responses":{"202":{"description":"Accepted — a new task is queued.","content":{"application/json":{"example":{"id":"b7c1d2e3-f4a5-4b6c-8d7e-9f0a1b2c3d4e","status":"pending"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"Only completed or failed tasks can be retried.","content":{"application/json":{"example":{"error":"only completed or failed tasks can be retried"}}}}}}},"/v1/dialogue":{"post":{"tags":["Dialogue"],"summary":"Create dialogue","description":"Convert a multi-speaker script to speech. Each line starting with `Name:` begins a new turn; following lines without a prefix continue that turn. Every speaker has its own provider, voice, model and settings. Poll Get history detail with the returned `id`.","operationId":"dialogue.create","security":[{"XiApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","speakers"],"properties":{"text":{"type":"string","description":"Script in `Speaker: text` lines, with at least two different speakers."},"speakers":{"type":"object","description":"Map of speaker name to `{provider, voice_id, model_id, language_code?, voice_settings?}`. Providers: `elevenlabs` or `minimax`."},"pause_between_turns":{"type":"number","description":"Silence between turns in seconds, 0–3.","default":0}}},"example":{"text":"Alice: Hello, how are you?\nBob: I am doing great, thanks for asking!","speakers":{"Alice":{"provider":"elevenlabs","voice_id":"rv30Fd6w5bnbL0kHzWlr","model_id":"eleven_multilingual_v2","language_code":"en"},"Bob":{"provider":"minimax","voice_id":"English_Aussie_Bloke","model_id":"speech-2.8-hd","language_code":"English"}},"pause_between_turns":0.3}}}},"responses":{"202":{"description":"Accepted — the dialogue task is queued.","content":{"application/json":{"example":{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","status":"pending"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}}}}},"/v1/speech-to-text":{"post":{"tags":["Speech to text"],"summary":"Speech to text","description":"Transcribe audio or video with ElevenLabs Scribe v2. Asynchronous: returns a `task_id`; poll Get transcription every couple of seconds. Credits are charged from the audio duration and refunded in full if the job fails. Requests without a valid `language_code` are rejected before any charge.","operationId":"stt.create","security":[{"XiApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","language_code"],"properties":{"file":{"type":"string","format":"binary","description":"Audio or video, max 90 MB (AAC, AIFF, OGG, MP3, Opus, WAV, WebM, FLAC, M4A, MP4)."},"language_code":{"type":"string","description":"ISO 639-1 or 639-3 code, e.g. `en`, `vie`."},"timestamps_granularity":{"type":"string","description":"`none`, `word` or `character`.","default":"word"},"diarize":{"type":"boolean","description":"Label each word with a `speaker_id`.","default":false},"num_speakers":{"type":"integer","description":"Maximum number of speakers, 1–32."},"diarization_threshold":{"type":"number","description":"0.0–1.5. Used when `diarize=true` and `num_speakers` is not set."},"tag_audio_events":{"type":"boolean","description":"Tag non-speech events such as (laughter).","default":true},"no_verbatim":{"type":"boolean","description":"Remove filler words and false starts.","default":false},"temperature":{"type":"number","description":"0.0–2.0."},"seed":{"type":"integer","description":"0–2147483647, for repeatable output."},"file_format":{"type":"string","description":"`other` or `pcm_s16le_16`.","default":"other"},"use_multi_channel":{"type":"boolean","description":"Transcribe up to 5 channels separately. Not with `diarize`.","default":false},"keyterms":{"type":"array","items":{"type":"string"},"description":"Repeatable. Terms to bias towards, max 1000, each under 50 characters."},"entity_detection":{"type":"array","items":{"type":"string"},"description":"Repeatable. `all`, `pii`, `phi`, `pci`, `other`, `offensive_language`."},"entity_redaction":{"type":"array","items":{"type":"string"},"description":"Repeatable. Subset of `entity_detection` to redact."},"entity_redaction_mode":{"type":"string","description":"`redacted`, `entity_type` or `enumerated_entity_type`.","default":"enumerated_entity_type"},"additional_formats":{"type":"array","items":{"type":"string"},"description":"Repeatable. `srt`, `txt`, `docx`, `html`, `pdf`, `segmented_json`."}}}}}},"responses":{"202":{"description":"Accepted — poll Get transcription.","content":{"application/json":{"example":{"task_id":"f534211b-b414-4697-bb58-a2a7a688a49f","status":"pending"}}}},"400":{"description":"Missing or unrecognised language code. Nothing is charged.","content":{"application/json":{"example":{"error":"missing_language_code"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}}}},"get":{"tags":["Speech to text"],"summary":"List transcriptions","description":"Your transcriptions, newest first. Transcripts are not included; read a single task to get its `result`.","operationId":"stt.list","security":[{"XiApiKey":[]}],"parameters":[{"name":"page","in":"query","required":false,"description":"Zero-based page number.","schema":{"type":"integer","default":0}},{"name":"page_size","in":"query","required":false,"description":"Items per page, max 100.","schema":{"type":"integer","default":30}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"tasks":[{"task_id":"f534211b-b414-4697-bb58-a2a7a688a49f","status":"completed","progress":100,"filename":"recording.mp3","audio_duration_secs":56.15,"credits_deducted":17,"created_at":"2026-10-11T13:50:48.000Z"}],"has_more":false}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/speech-to-text/{task_id}":{"get":{"tags":["Speech to text"],"summary":"Get transcription","description":"Poll a transcription until `status` is `completed` or `failed`. `result` appears once completed; on failure `detail_error` explains why and the credits have been refunded.","operationId":"stt.get","security":[{"XiApiKey":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"description":"The `task_id` returned on submission.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"task_id":"f534211b-b414-4697-bb58-a2a7a688a49f","status":"completed","progress":100,"filename":"recording.mp3","audio_duration_secs":56.15,"credits_deducted":17,"created_at":"2026-10-11T13:50:48.000Z","updated_at":"2026-10-11T13:50:56.000Z","result":{"language_code":"eng","language_probability":0.97,"text":"Hello everyone.","words":[{"text":"Hello","start":0,"end":0.32,"type":"word","logprob":-0.002,"speaker_id":"speaker_0"},{"text":" ","start":0.32,"end":0.4,"type":"spacing","logprob":-0.001,"speaker_id":"speaker_0"},{"text":"everyone.","start":0.4,"end":0.92,"type":"word","logprob":-0.04,"speaker_id":"speaker_0"}],"additional_formats":[],"transcription_id":"Qe71uRUkuArC2JNlRsGy","audio_duration_secs":56.15}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}}}},"delete":{"tags":["Speech to text"],"summary":"Delete transcription","description":"Permanently delete a finished transcription and its stored audio. Deleting does not refund credits.","operationId":"stt.delete","security":[{"XiApiKey":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"description":"The transcription to delete.","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"example":{"deleted":true}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"The task is still pending or processing.","content":{"application/json":{"example":{"error":"task_still_running","message":"This transcription is still running. Wait for it to finish before deleting it."}}}}}}},"/v1/voice-changer":{"post":{"tags":["Voice Changer"],"summary":"Voice changer","description":"Speech to speech: re-voice an audio file with an ElevenLabs voice (max 50 MB, 5 minutes). Asynchronous; poll Get history detail. Credits are based on the audio duration.","operationId":"changer.create","security":[{"XiApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["audio","voice_id"],"properties":{"audio":{"type":"string","format":"binary","description":"Source audio, max 50 MB and 5 minutes."},"voice_id":{"type":"string","description":"Target ElevenLabs voice ID."},"model_id":{"type":"string","description":"ElevenLabs speech-to-speech model.","default":"eleven_multilingual_sts_v2"},"remove_background_noise":{"type":"string","description":"`true` to remove background noise.","default":"false"},"voice_settings":{"type":"string","description":"JSON string with `stability`, `similarity_boost`, `style`, `use_speaker_boost`."}}}}}},"responses":{"202":{"description":"Accepted","content":{"application/json":{"example":{"task_id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","status":"pending"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}}}}},"/v1/voice-changer/history":{"get":{"tags":["Voice Changer"],"summary":"Get history list","description":"Voice changer tasks, newest first.","operationId":"changer.history","security":[{"XiApiKey":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"description":"Tasks per page, 1–100.","schema":{"type":"integer","default":30}},{"name":"page","in":"query","required":false,"description":"Zero-based page number.","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"tasks":[{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"completed","progress":100,"voice_id":"rv30Fd6w5bnbL0kHzWlr","model_id":"eleven_multilingual_sts_v2","source_audio_url":"https://api.vocallab.net/audio/5f0c2a4e-1d1b-4c8e-9a51-2a3b4c5d6e7f.mp3?exp=1767225600&sig=…","result":{"audio_url":"https://api.vocallab.net/audio/9b19d3e2-7c68-4eca-be48-e9917682d73e.mp3?exp=1767225600&sig=…"},"metadata":{"voice_settings":{"stability":0.5,"similarity_boost":0.75},"remove_noise":false},"credits_deducted":500,"error":null,"detail_error":null,"created_at":"2026-10-11T10:30:00.000Z","updated_at":"2026-10-11T10:30:15.000Z"}],"has_more":false}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/voice-changer/history/{id}":{"get":{"tags":["Voice Changer"],"summary":"Get history detail","description":"One voice changer task, for polling.","operationId":"changer.get","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"completed","progress":100,"voice_id":"rv30Fd6w5bnbL0kHzWlr","model_id":"eleven_multilingual_sts_v2","source_audio_url":"https://api.vocallab.net/audio/5f0c2a4e-1d1b-4c8e-9a51-2a3b4c5d6e7f.mp3?exp=1767225600&sig=…","result":{"audio_url":"https://api.vocallab.net/audio/9b19d3e2-7c68-4eca-be48-e9917682d73e.mp3?exp=1767225600&sig=…"},"metadata":{"voice_settings":{"stability":0.5,"similarity_boost":0.75},"remove_noise":false},"credits_deducted":500,"error":null,"detail_error":null,"created_at":"2026-10-11T10:30:00.000Z","updated_at":"2026-10-11T10:30:15.000Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}}}},"delete":{"tags":["Voice Changer"],"summary":"Delete task","description":"Delete a finished voice changer task with its source and result audio.","operationId":"changer.delete","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"message":"deleted"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"The task is still pending or processing.","content":{"application/json":{"example":{"error":"task_still_running","message":"This task is still running. Wait for it to finish before deleting it."}}}}}}},"/v1/voice-changer/history/{id}/retry":{"post":{"tags":["Voice Changer"],"summary":"Retry task","description":"Re-run a completed or failed voice changer task with its original audio. Credits are charged again from the audio duration.","operationId":"changer.retry","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"responses":{"202":{"description":"Accepted — a new task is queued.","content":{"application/json":{"example":{"task_id":"b7c1d2e3-f4a5-4b6c-8d7e-9f0a1b2c3d4e","status":"pending"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"Only completed or failed tasks can be retried.","content":{"application/json":{"example":{"error":"only completed or failed tasks can be retried"}}}},"422":{"description":"The stored source file is no longer available. Nothing is charged.","content":{"application/json":{"example":{"error":"cannot retry: source file no longer available"}}}}}}},"/v1/aidubbing/upload/init":{"post":{"tags":["Dubbing"],"summary":"1. Init upload","description":"Step 1 of an AI dubbing job: open an upload session. Sources up to 2 GB and 2.5 hours (MP3, WAV, AAC, M4A, MP4, MOV). Flow: init → chunk (×N) → complete.","operationId":"dubbing.init","security":[{"XiApiKey":[]}],"responses":{"200":{"description":"Upload session created","content":{"application/json":{"example":{"upload_id":"0f8fad5b-d9cb-469f-a165-70867728950e","chunk_size":52428800}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/aidubbing/upload/chunk":{"post":{"tags":["Dubbing"],"summary":"2. Upload chunks","description":"Step 2: upload each part of the file at its zero-based index, slicing at `chunk_size`. Parts may arrive in any order or in parallel, and re-posting an index replaces it. Max 100 MB per part and 2 GB per session.","operationId":"dubbing.chunk","security":[{"XiApiKey":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["upload_id","index","chunk"],"properties":{"upload_id":{"type":"string","description":"Session ID from init."},"index":{"type":"integer","description":"Zero-based part index, max 511."},"chunk":{"type":"string","format":"binary","description":"The file slice for this index."}}}}}},"responses":{"200":{"description":"Part stored","content":{"application/json":{"example":{"index":0,"received":true}}}},"400":{"description":"Invalid index, missing data, part too large or session over 2 GB.","content":{"application/json":{"example":{"error":"chunk too large"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"Unknown upload session.","content":{"application/json":{"example":{"error":"upload session not found"}}}}}}},"/v1/aidubbing/upload/complete":{"post":{"tags":["Dubbing"],"summary":"3. Complete & start dubbing","description":"Final step: reassemble parts `0..total_chunks-1` and start the dubbing job. Credits are reserved upfront from the source duration. Poll Get history detail with the returned `task_id`. Once assembly starts the session is consumed, whether or not the job is accepted.","operationId":"dubbing.complete","security":[{"XiApiKey":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["upload_id","total_chunks","target_language","source_language","voice_id"],"properties":{"upload_id":{"type":"string","description":"Session ID from init."},"total_chunks":{"type":"integer","description":"Number of parts uploaded, 1–512."},"filename":{"type":"string","description":"Original file name, shown in history.","default":"upload"},"content_type":{"type":"string","description":"MIME type of the source, e.g. `video/mp4`."},"target_language":{"type":"string","description":"ISO 639-1 code to dub into: af, ar, hy, as, az, be, bn, bs, bg, ca, ceb, ny, zh, hr, cs, da, nl, en, et, fil, fi, fr, gl, ka, de, el, gu, ha, he, hi, hu, is, id, ga, it, ja, jv, kn, kk, ky, ko, lv, ln, lt, lb, mk, ms, ml, mr, ne, no, ps, fa, pl, pt, pa, ro, ru, sr, sd, sk, sl, so, es, sw, sv, ta, te, th, tr, uk, ur, vi, cy, nn, yue. CapCut supports en, zh, es, id, pt, fr, de, vi, ja, th, tr, it."},"source_language":{"type":"string","description":"Source language code (same list plus `mi`, `tl`). `auto` is not accepted."},"provider":{"type":"string","description":"`minimax` (speech-2.8-hd), `elevenlabs` (eleven_v3) or `capcut`.","default":"minimax"},"voice_id":{"type":"string","description":"MiniMax `uniq_id` or cloned voice ID, ElevenLabs voice ID, or CapCut voice ID matching the target language."}}}}}},"responses":{"202":{"description":"Accepted — the dubbing task is queued.","content":{"application/json":{"example":{"task_id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","status":"pending"}}}},"400":{"description":"Missing part or invalid parameters.","content":{"application/json":{"example":{"error":"missing chunk 2"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}},"404":{"description":"Unknown upload session.","content":{"application/json":{"example":{"error":"upload session not found"}}}}}}},"/v1/aidubbing/history":{"get":{"tags":["Dubbing"],"summary":"Get history list","description":"AI dubbing tasks, newest first.","operationId":"dubbing.history","security":[{"XiApiKey":[]}],"parameters":[{"name":"page_size","in":"query","required":false,"description":"Tasks per page, 1–100.","schema":{"type":"integer","default":30}},{"name":"page","in":"query","required":false,"description":"Zero-based page number.","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"tasks":[{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"completed","progress":100,"source_lang":"en","target_lang":"vi","provider":"minimax","voice_id":"Wise_Woman","model_id":"speech-2.8-hd","source_audio_url":"https://api.vocallab.net/audio/0d7f1c9e-6a1b-4f3e-8c2d-1e2f3a4b5c6d.mp3?exp=1767225600&sig=…","result":{"audio_url":"https://api.vocallab.net/audio/7a1e9c2b-3d4f-4a5b-8c6d-9e0f1a2b3c4d.mp4?exp=1767225600&sig=…","srt_url":"https://api.vocallab.net/audio/3c2b1a0f-9e8d-4c7b-a6f5-e4d3c2b1a0f9.srt?exp=1767225600&sig=…"},"metadata":{"source_file_name":"interview.mp4","original_video_url":null,"voice_name":"Wise Woman"},"credits_deducted":18000,"error":null,"detail_error":null,"created_at":"2026-10-11T10:30:00.000Z","updated_at":"2026-10-11T10:35:15.000Z"}],"has_more":false}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}}}}},"/v1/aidubbing/history/{id}":{"get":{"tags":["Dubbing"],"summary":"Get history detail","description":"One dubbing task, for polling. `result.audio_url` is the dubbed video (MP4) for video sources, otherwise audio; `result.srt_url` holds translated subtitles.","operationId":"dubbing.get","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"id":"9b19d3e2-7c68-4eca-be48-e9917682d73e","user_id":"user_123","status":"completed","progress":100,"source_lang":"en","target_lang":"vi","provider":"minimax","voice_id":"Wise_Woman","model_id":"speech-2.8-hd","source_audio_url":"https://api.vocallab.net/audio/0d7f1c9e-6a1b-4f3e-8c2d-1e2f3a4b5c6d.mp3?exp=1767225600&sig=…","result":{"audio_url":"https://api.vocallab.net/audio/7a1e9c2b-3d4f-4a5b-8c6d-9e0f1a2b3c4d.mp4?exp=1767225600&sig=…","srt_url":"https://api.vocallab.net/audio/3c2b1a0f-9e8d-4c7b-a6f5-e4d3c2b1a0f9.srt?exp=1767225600&sig=…"},"metadata":{"source_file_name":"interview.mp4","original_video_url":null,"voice_name":"Wise Woman"},"credits_deducted":18000,"error":null,"detail_error":null,"created_at":"2026-10-11T10:30:00.000Z","updated_at":"2026-10-11T10:35:15.000Z"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}}}},"delete":{"tags":["Dubbing"],"summary":"Delete task","description":"Delete a finished dubbing task and its stored files.","operationId":"dubbing.delete","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}}],"responses":{"200":{"description":"OK - task deleted","content":{"application/json":{"example":{"status":"deleted"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"The task is still pending or processing.","content":{"application/json":{"example":{"error":"task_still_running","message":"This task is still running. Wait for it to finish before deleting it."}}}}}}},"/v1/aidubbing/history/{id}/retry":{"post":{"tags":["Dubbing"],"summary":"Retry task","description":"Re-run a completed or failed dubbing task from its stored source, without uploading again. The original credit cost is charged again.","operationId":"dubbing.retry","security":[{"XiApiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID returned when the task was created.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional. Re-sending the same key returns the original task instead of creating a new one.","schema":{"type":"string","minLength":12,"maxLength":120}}],"responses":{"202":{"description":"Accepted — a new task is queued.","content":{"application/json":{"example":{"task_id":"b7c1d2e3-f4a5-4b6c-8d7e-9f0a1b2c3d4e","status":"pending"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"example":{"error":"invalid api key"}}}},"402":{"description":"Not enough credits. `required` is the cost of the request.","content":{"application/json":{"example":{"error":"insufficient credits","required":18000}}}},"404":{"description":"The task does not exist or belongs to another account.","content":{"application/json":{"example":{"error":"task not found"}}}},"409":{"description":"Only completed or failed tasks can be retried.","content":{"application/json":{"example":{"error":"only completed or failed tasks can be retried"}}}},"422":{"description":"The stored source file is no longer available. Nothing is charged.","content":{"application/json":{"example":{"error":"cannot retry: source file no longer available"}}}}}}},"/v1/quotes":{"post":{"summary":"Quote one task before submitting it","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"description":"User-bound short-lived quote"}},"tags":["VocalLab extensions"]}},"/v1/tasks":{"post":{"summary":"Submit any configured tool using kind, native payload and private upload_id","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":12,"maxLength":120}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskRequest"},"examples":{"scenes":{"value":{"kind":"scenes","payload":{"provider":"elevenlabs","model_id":"eleven_v3","voice_id":"VOICE_FROM_VOCALLAB","language_code":"vi","scenes":[{"index":1,"text":"Xin chào."},{"index":2,"text":"Chào mừng bạn."}],"pauseSeconds":0.3}}},"srt":{"value":{"kind":"srt","payload":{"provider":"elevenlabs","model_id":"eleven_v3","voice_id":"VOICE_FROM_VOCALLAB","language_code":"vi","cues":[{"index":1,"startMs":0,"endMs":3000,"text":"Xin chào."}],"fit":"speed"}}}}}}},"responses":{"202":{"description":"Accepted task"},"409":{"description":"Idempotency conflict"}},"tags":["VocalLab extensions"]},"get":{"summary":"Paginated private task history","responses":{"200":{"description":"Tasks"}},"tags":["VocalLab extensions"]}},"/v1/tasks/{id}/retry-input":{"get":{"summary":"Read canonical studio input for an owned settled task","description":"Returns {input} in studio camelCase shape, suitable for POST /api/quotes when using a browser session. API-only clients reconstruct their native /v1 payload or use the retry endpoint with a new Idempotency-Key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Canonical input"},"404":{"description":"Absent or unowned task"},"409":{"description":"Unsettled task cannot be retried"}},"tags":["VocalLab extensions"]}},"/v1/history/{id}/cancel":{"post":{"summary":"Cancel an owned task","responses":{"200":{"description":"Cancelled when cancellable"}},"tags":["VocalLab extensions"]}},"/v1/uploads":{"post":{"summary":"Upload audio/video into private VocalLab storage","responses":{"201":{"description":"Validated upload_id"}},"tags":["VocalLab extensions"]}},"/v1/uploads/init":{"post":{"summary":"Begin resumable dubbing upload","responses":{"201":{"description":"Upload manifest"}},"tags":["VocalLab extensions"]}},"/v1/uploads/{id}/chunks/{index}":{"post":{"summary":"Upload one binary chunk with replay validation","responses":{"200":{"description":"Manifest with received chunks"}},"tags":["VocalLab extensions"]}},"/v1/uploads/{id}/complete":{"post":{"summary":"Assemble and probe uploaded media","responses":{"200":{"description":"Ready private upload"}},"tags":["VocalLab extensions"]}},"/v1/voices":{"get":{"summary":"List public or user-owned library voices","parameters":[{"name":"provider","in":"query","schema":{"type":"string"}},{"name":"source","in":"query","schema":{"enum":["default","shared","mine","recents"]}},{"name":"search","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Sanitized VocalLab voice metadata with local protected preview URLs"}},"tags":["VocalLab extensions"]}},"/v1/audio/{id}":{"get":{"summary":"Download owned result with VocalLab API key","responses":{"200":{"description":"Audio bytes"},"404":{"description":"Absent or unowned"}},"tags":["VocalLab extensions"]}},"/v1/artifacts/{id}":{"get":{"summary":"Download owned media or transcript artifact","responses":{"200":{"description":"Artifact bytes"}},"tags":["VocalLab extensions"]}}},"x-vocallab-differences":["Keys are VocalLab customer keys, never GenMax merchant keys. GET /v1/api-keys returns a masked key because only a hash is stored.","Requests are validated task types, quoted and charged by VocalLab, persisted locally, and processed by the task service; arbitrary paths and headers cannot be proxied.","Task history and mutations are restricted to the key owner. Missing, foreign, or deleted-user tasks are returned as not found.","Retry creates a new task and returns its ID; poll the returned ID.","Result and preview URLs are short-lived signed VocalLab links. No merchant catalogue credential or raw provider URL is exposed.","scenes and srt are VocalLab batch operations: each part is a real upstream TTS job, journalled separately, then composed privately with FFmpeg.","API keys have a per-minute limit and a persisted daily request quota. Browser key management is available under /api/developer/keys with a VocalLab session and CSRF protection."]}