Video translation
/v1/dubbingmultipart/form-datahttps://api.sonilo.com/v1/dubbingSend API requests to https://api.sonilo.com. The platform.sonilo.com/docs pages are documentation only and are not API endpoints.
curl -X POST https://api.sonilo.com/v1/dubbing \
-H "Authorization: Bearer $SONILO_API_KEY" \
-F "[email protected]" \
-F 'languages=["ja","tr"]' \
-F "subtitles[ja][email protected]" \
-F "subtitles[tr]=https://cdn.example.com/episode1.tr.vtt" \
-F "export_srt=true"
# => {"task_id": "9f5f2f7e-...", "status": "processing"}
curl https://api.sonilo.com/v1/tasks/9f5f2f7e-... \
-H "Authorization: Bearer $SONILO_API_KEY"
# poll until "status" is "succeeded" or "failed"{
"task_id": "9f5f2f7e-…",
"status": "processing",
"subtitle_preflight": {
"ja": {
"status": "prepared_review_required",
"cue_count": 42,
"issues": [],
"changes_count": 0
},
"tr": {
"status": "prepared_review_required",
"cue_count": 38,
"issues": [],
"changes_count": 0
}
}
}Authorization
Authenticate via Bearer token. Generate keys at the API Keys page and pass them in the Authorization header on every request. Keep keys server-side, for example in SONILO_API_KEY.
Authorization: Bearer sk_your_api_keyStore the key server-side, commonly as SONILO_API_KEY. A 401 means the key is missing, invalid, or revoked. A 403 means the key is valid but the account does not have access to that endpoint or workspace.
Body Parameters
videofilevideo or video_url, not both. Accepted formats: mp4, mov, webm, m4v, gif (animated). Max file size: default 300MB. Max duration: 300 sec.video_urlstringvideo or video_url, not both. Must be a public https:// URL — plain http:// is rejected (the dubbing pipeline requires https); private/internal addresses are rejected.languagesstring["es", "fr"]. Defaults to ["zh_cn", "es", "fr"] when omitted. Billed as video duration × number of languages requested.- en
- English
- zh_cn
- Chinese (Simplified)
- ja
- Japanese
- ko
- Korean
- pt
- Portuguese
- pt_br
- Portuguese (Brazil)
- es
- Spanish
- es_419
- Spanish (Latin America)
- de
- German
- fr
- French
- it
- Italian
- ru
- Russian
- th
- Thai
- ar
- Arabic
- tr
- Turkish
- vi
- Vietnamese
- id
- Indonesian
- ta
- Tamil
- ml
- Malayalam
- kn
- Kannada
- gu
- Gujarati
- pa_in
- Punjabi (India)
- sd_in
- Sindhi (India)
- hi
- Hindi
pt and es are unqualified Portuguese and Spanish. Request pt_br or es_419 when the region matters — they are additional targets, not replacements. Punjabi and Sindhi are available in their Indian variants only — that is what pa_in and sd_in say.
duckingbooleantrue to apply Sonilo ducking — the background music/effects bed is lowered while the dubbed voice is speaking. Defaults to false: the dubbed voice is mixed over the bed unchanged.lipsyncbooleantrue. With lip sync on, the speaker's mouth is re-rendered to match the dubbed speech. Set lipsync=false to leave the picture completely untouched instead — the video is returned at its original resolution and frame rate rather than re-rendered, and only the audio is replaced, so the mouths keep moving to the original language. Useful for footage with no on-camera speaker, or when preserving the exact original picture matters more than matching lip movement. The background music/effects bed is rebuilt either way, so ducking behaves the same.subtitles[<language>]file | stringlanguages, sent as subtitles[language]: an uploaded .srt or .vtt file, or a public https:// URL. Example: subtitles[ja][email protected], subtitles[tr]=https://cdn.example.com/episode1.tr.vtt. Scripts are in the target language and the dub speaks them verbatim instead of translating the source speech. Every requested language needs exactly one script. Max file size: 1 MiB each. Validated before billing — a rejected script returns 422 with code SUBTITLE_PREFLIGHT_BLOCKED and, under details, the report keyed by language.export_srtbooleanfalse. Requires subtitles. Returns every language's lines re-timed against its dubbed audio as subtitles on the finished task.Response
task_idstringstatusstringoutputsobjectsubtitlesobjectexport_srt was set and the task succeeded — a map of language code to a temporary download URL for that language's re-timed .srt.subtitle_preflightobjectstatus, cue_count, issues, changes_count, report_url.subtitle_exportobjectexport_srt was set — per language: status (exported, exported_review_required or blocked), issues, alignment_loss, error, report_url. A blocked export never fails the task.trial_previewobjectpreview_seconds, source_duration_seconds, trimmed, languages, full_video_cost_usd (what translating the full video costs) and a message. Repeated on the task in every state.duration_secondsnumbercurl -X POST https://api.sonilo.com/v1/dubbing \
-H "Authorization: Bearer $SONILO_API_KEY" \
-F "[email protected]" \
-F 'languages=["ja","tr"]' \
-F "subtitles[ja][email protected]" \
-F "subtitles[tr]=https://cdn.example.com/episode1.tr.vtt" \
-F "export_srt=true"
# => {"task_id": "9f5f2f7e-...", "status": "processing"}
curl https://api.sonilo.com/v1/tasks/9f5f2f7e-... \
-H "Authorization: Bearer $SONILO_API_KEY"
# poll until "status" is "succeeded" or "failed"{
"task_id": "9f5f2f7e-…",
"status": "processing",
"subtitle_preflight": {
"ja": {
"status": "prepared_review_required",
"cue_count": 42,
"issues": [],
"changes_count": 0
},
"tr": {
"status": "prepared_review_required",
"cue_count": 38,
"issues": [],
"changes_count": 0
}
}
}