Introduction
The Oiiyao API reference, with endpoint documentation, code examples, and request parameters. Integrate video processing such as video translation, multi-speaker translation, smart erasure, subtitle translation, face swap, and lip sync, alongside audio processing such as voice cloning and text-to-speech.
Base URL
https://api.oiiyao.comAuthentication
All API requests must include your API Key in the Authorization header, format: Bearer YOUR_API_KEY.
| Header | Description |
|---|---|
| Authorization | Format: Bearer YOUR_API_KEY |
| Accept-Language | Optional. Language of error messages and display names such as age_range, voice names and the pricing description: en for English; omit it for Chinese (default). Branch on codes such as error.code, task_type, age_range_code and voice_id, not on these texts. The official SDKs (Java, Python, JavaScript) have no language option yet and don't send this header; for English responses, call the HTTP API directly with Accept-Language: en. |
Response Format
All API responses use a unified JSON envelope format.
Success Response
{
"success": true,
"data": {
"task_id": "551",
"task_type": "video_translation",
"status": "pending"
},
"usage": {
"credits_used": 60,
"credits_remaining": 10000
}
}Error Response
{
"success": false,
"error": {
"type": "validation_error",
"code": "missing_field",
"message": "video_url is required",
"param": "video_url"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
| success | boolean | Whether the request was successful |
| data | object | Business data object |
| usage | object | Credits usage info (only returned when credits are consumed) |
| usage.credits_used | integer | Estimated credits for this request. Video tasks may omit it at submission because the duration is not known yet; the amount actually charged is the task's credits_used once it finishes |
| usage.credits_remaining | integer | Remaining credits |
| error | object | Error info object (only returned on failure) |
| error.type | string | Error type identifier |
| error.code | string | Error code for programmatic handling. Common values: missing_field / invalid_param (request problems), business_error (a business rule rejected the request), insufficient_credits (not enough credits), rate_limit_exceeded (too many requests), duplicate_request (the previous request with the same idempotency_key is still being processed: returned with HTTP 200 and success false; retry later with the same key to get the original result, and do not switch to a new key or you will be charged twice), 10100 (an internal server error unrelated to your parameters; retry later as is); authentication and URL checks use numeric codes |
| error.message | string | Human-readable description you can show to users; Chinese or English according to the Accept-Language header (Chinese if absent) |
| error.param | string | Related parameter name (optional) |
Async tasks and callbacks
Every generation endpoint is asynchronous: the call returns a task_id right away, and you get the result either by polling the task or by waiting for a callback to your callback_url.
End-to-end flow
- 1
Submit the task and read the task id from data.task_id in the response.
- 2
Poll the task endpoint until the status reaches a terminal state. SeeTask Statuses
- 3
When the task completes, read the result URLs from data.output; the fields vary by task type.
- 4
Result URLs are temporary signed links; get a fresh one when it expires:Refresh URL
Callback protocol
| Item | Value |
|---|---|
| Method | POST |
| Content type | application/json |
| Field naming | snake_case |
| Success | Any 2xx response from your endpoint |
| Per-attempt timeout | 15s |
| Retries | Up to 3 retries after the first attempt, spaced 1s, 5s and 30s (4 attempts in total) |
Callback body example
{
"event": "task.completed",
"task_id": "551",
"status": "completed",
"timestamp": "2026-01-01T12:00:00Z",
"task_type": "video_translation",
"output": {
"video_url": "https://files.oiiyao.com/...",
"subtitle_url": "https://files.oiiyao.com/..."
}
}Before you wire it up
- The fields inside output depend on the task type: vocals_url and background_url for audio separation, audio_url for text-to-speech, and video_url plus subtitle_url for everything else.
- A failed callback only carries status: failed — the body has no error reason. Call the task endpoint and read error_message to find out why.
- callback_url must be a publicly reachable http(s) URL. A URL that fails our security check is skipped silently, with no notice.
- The result URLs inside a callback are temporary signed links too, and the body carries no expiry time — copy them to your own storage promptly.
- Callbacks are not signed. Use an unguessable callback_url, and confirm each notification by looking its task_id up through the API.
Account
Get Balance
Query current account credit balance and rate limit information.
Response
| Field | Description |
|---|---|
| data.credits_remaining | Remaining credits |
| data.plan | Current plan |
| data.expires_at | Plan expiration time |
| data.rate_limits | Rate limit information |
| data.rate_limits.requests_per_minute | Requests per minute limit |
| data.rate_limits.queries_per_second | Queries per second limit |
Usage History
Query account credit usage history with date range filtering and cursor pagination.
Query Parameters
Start date (format: yyyy-MM-dd)
End date (format: yyyy-MM-dd)
Pagination cursor (from previous response's next_cursor)
Items per page (max 100, default 20)
Response
| Field | Description |
|---|---|
| data.records | Usage records list |
| data.records[].task_id | Task ID |
| data.records[].task_type | Task type |
| data.records[].credits_used | Credits consumed |
| data.records[].created_at | Created at (ISO 8601) |
| data.total_credits_used | Total credits consumed |
| data.next_cursor | Next page cursor |
| data.has_more | Whether more data exists |
Pricing
Query credit pricing for all task types.
Response
| Field | Description |
|---|---|
| data.pricing | Pricing list |
| data.pricing[].task_type | Task type |
| data.pricing[].credits_per_minute | Credits per minute |
| data.pricing[].description | Display name of the task type (follows Accept-Language) |
| data.pricing[].language | Language |
Tasks
Get Task
Query task details by task ID, including processing status and result files.
Path Parameters
Task ID
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status (pending / processing / completed / failed) |
| data.progress | Processing progress (0-100) |
| data.name | Task name |
| data.source_language | Source language |
| data.target_language | Target language |
| data.output | Output file information |
| data.output.video_url | Result video URL |
| data.output.subtitle_url | Subtitle file URL |
| data.output.audio_url | Audio file URL (returned for text_to_speech tasks) |
| data.output.expires_at | Output URL expiration time (ISO 8601). URLs are valid for 2 hours. Use POST /files/refresh-url to get new URLs after expiration |
| data.credits_used | Credits actually charged (the settled amount). Only returned for completed / failed tasks: for completed tasks it is the final settled amount, which may differ from the usage.credits_used estimate at submission; for failed tasks the reserved credits are returned, so it is usually 0 (voice clone fees for multi-speaker cast roles that were already cloned successfully are not refunded and are included) |
| data.created_at | Created at (ISO 8601) |
| data.completed_at | Completed at (ISO 8601) |
| data.error_message | Failure reason (only for failed tasks) you can show to users; Chinese or English according to the Accept-Language header (Chinese if absent) |
List Tasks
Query task list with status and type filtering, using cursor pagination.
Query Parameters
Filter by status (pending / processing / completed / failed)
Filter by task type
Pagination cursor
Items per page (max 100, default 20)
Response
| Field | Description |
|---|---|
| data.tasks | Task list |
| data.next_cursor | Next page cursor |
| data.has_more | Whether more data exists |
Videos
Video Translation
Create a video translation task with multi-language support and dubbing.
Request Body
Source video URL (HTTPS)
Source language codeLanguage Codes
Target language codeLanguage Codes
Clone the original speaker's voice (default: false). When true, voice_id is ignored and a flat 20-credit clone fee is added per task (independent of video length)
Voice ID (required when voice_clone is false). Use GET /voices to list available voices
Burn the translated subtitles into the output video (default: true). When false, the output video has no subtitles and finishes faster, especially for long videos
Erase the subtitles burned into the source video before compositing (default: false). If the source has hard subtitles and they are not erased, the old and new subtitles overlap. The subtitle removal add-on is charged separately. The source video must be 1080p or lower (long side at most 1920 px); downscale higher-resolution videos to 1080p before submitting
Where to read the original subtitles from (default: audio). audio = speech recognition; screen = recognize the subtitles burned into the picture, for videos with on-screen text but no speech. screen only supports source_language zh or en and cannot be combined with voice_clone=true
Re-sync the speaker's lip movements to the translated voiceover (default: false), for videos where the speaker talks to the camera. The lip sync add-on is charged separately and processing takes longer
Task name
Task completion callback URL
Idempotency key (prevents duplicate submissions)
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Smart Eraser
Create a subtitle/watermark removal task.
Request Body
Source video URL (HTTPS)
Task name
Erasure regions array (required when erasure_mode is manual; currently only the first region is used). Each item: x (left edge, 0-1), y (top edge, 0-1), width (0-1), height (0-1). Coordinates are relative to video dimensions
Erasure mode (default: auto). auto=auto-detect and erase subtitles/watermarks, no normalized_regions needed; manual=erase content within specified region, normalized_regions required
Task completion callback URL
Idempotency key
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Subtitle Translation
Create a subtitle translation task to extract speech and translate to subtitles.
Request Body
Source video URL (HTTPS)
Source language codeLanguage Codes
Target language codeLanguage Codes
Task name
Task completion callback URL
Idempotency key
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Face Swap
Create a face swap task to replace faces in video with a source image.
Request Body
Source video URL (HTTPS)
Target face image URL (HTTPS)
Task name
Task completion callback URL
Idempotency key
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Lip Sync
Create a lip sync task to synchronize lip movements with audio.
Request Body
Source video URL (HTTPS)
Audio file URL (HTTPS)
Task name
Task completion callback URL
Idempotency key
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Multi-Speaker Video Translation
Submit a multi-speaker video translation task. The system automatically identifies speakers and assigns individual voices for translated dubbing. subtitle_source and lip_sync are not supported on this endpoint.
Request Body
Video file URL (S3 presigned URL or publicly accessible URL)
Source language codeLanguage Codes
Target language codeLanguage Codes
Burn the translated subtitles into the output video (default: true). When false, the output video has no subtitles and finishes faster, especially for long videos
Erase the subtitles burned into the source video before compositing (default: false), same as the video translation endpoint. The subtitle removal add-on is charged separately. The source video must be 1080p or lower (long side at most 1920 px)
Task name (optional)
Callback URL for task completion notification
Idempotency key (prevents duplicate submissions)
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Audio
Voice Clone
Clone a voice from an audio sample. Synchronous API, returns voice ID.
Request Body
Audio file URL (HTTPS)
Voice name
Response
| Field | Description |
|---|---|
| data.voice_id | Voice ID |
| data.name | Voice name |
| data.type | Voice type |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Text to Speech
Create a text-to-speech task, processed asynchronously.
Request Body
Text to convert
Voice ID
Language codeLanguage Codes
Task name
Task completion callback URL
Idempotency key
Delivery tone. Allowed values: auto / neutral / happy / sad / angry / surprised / fearful / calm. Default: auto. Both auto and neutral mean no tone is applied (it is no longer inferred from the text). Note: whether a tone can be performed depends on the model behind the voice; unsupported voices read the text as written — check the voice lookup endpoint first.
Number / date pronunciation. Allowed values: auto / on / off. Default: auto. on = read as full words (e.g., "$5" → "five dollars"); off = read literal characters.
Response
| Field | Description |
|---|---|
| data.task_id | Task ID |
| data.task_type | Task type |
| data.status | Task status |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Voices
List Voices
Query available voices with language and gender filtering.
Query Parameters
Filter by language using the two-letter codes from the language code table (e.g., zh); zh-CN returns an empty list
Filter by gender (male / female)
Response
| Field | Description |
|---|---|
| data[].voice_id | Voice ID |
| data[].name | Voice name (display name, follows Accept-Language: with en, system voices with a Chinese name return their pinyin name; others are unchanged). Reference voices by voice_id |
| data[].language | Language |
| data[].gender | Gender |
| data[].age_range | Age range (display name, follows Accept-Language) |
| data[].age_range_code | Age range code: child / young_adult / middle_aged_senior (same in every language) |
| data[].preview_url | Preview URL |
| data[].type | Voice type: always system, as this endpoint lists system voices only |
Files
Get Upload URL
Get a pre-signed upload URL for direct file upload to object storage. Uploaded files that are not used by any task within 30 days are deleted automatically, so submit your task within that window.
Request Body
File name
File size in bytes
File MD5 (optional, for deduplication)
Response
| Field | Description |
|---|---|
| data.file_id | File ID |
| data.upload_url | Pre-signed upload URL |
| data.upload_method | Upload method (PUT) |
| data.upload_headers | Required upload headers |
| data.expires_at | Upload URL expiration time |
| data.url | File download URL (returned immediately for duplicates) |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Confirm Upload
Confirm file upload completion and get download URL.
Request Body
File ID (from Get Upload URL response)
Response
| Field | Description |
|---|---|
| data.file_id | File ID |
| data.url | File download URL |
| data.expires_at | URL expiration time (ISO 8601) |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Refresh URL
Refresh file download URL (use when URL has expired).
Request Body
File ID
Response
| Field | Description |
|---|---|
| data.file_id | File ID |
| data.url | New file download URL |
| data.expires_at | URL expiration time (ISO 8601) |
Requests go to the live API: a successful call creates a task on your account and spends credits.
Error Types
| Type | HTTP Status | Description |
|---|---|---|
| authentication_error | 401 | API Key missing, invalid, or disabled |
| validation_error | 400 | Invalid parameters, missing fields, URL validation failure, or a business rule rejected the request (code business_error; message explains why, e.g. an unsupported language) |
| rate_limit_error | 429 | Rate limit exceeded |
| permission_error | 403 | HTTPS required or insufficient permissions |
| insufficient_credits | 402 | Not enough credits (code insufficient_credits), checked against the estimated cost at submission. Video tasks reserve credits only after the media is downloaded and its duration is known; if the balance is short at that point the task ends as failed, and the reason is in the task's error_message |
| not_found | 404 | Resource not found |
| internal_error | 500 | Internal server error |
Task Statuses
| Status | Description |
|---|---|
| pending | Pending — Task submitted, waiting to be processed |
| processing | Processing — Task is being executed |
| completed | Completed — Task finished successfully |
| failed | Failed — Task execution failed |
Task Types
| Task Type | Description |
|---|---|
| video_translation | Video Translation |
| multi_speaker_translation | Multi-Speaker Translation |
| lip_sync | Lip Sync |
| smart_erasure | Smart Eraser |
| subtitle_translation | Subtitle Translation |
| face_swap | Face Swap |
| text_to_speech | Text to Speech |
Language Codes
The API accepts ISO 639-1 standard language codes. Source languages reflect speech-recognition (ASR) coverage; target languages reflect text-to-speech (TTS) coverage. The supported lists are below.
Source Languages (source_language)
| Code | Language |
|---|---|
| zh | Chinese |
| en | English |
| ja | Japanese |
| ko | Korean |
| ru | Russian |
| de | German |
| fr | French |
| ar | Arabic |
| es | Spanish |
| it | Italian |
| vi | Vietnamese |
| pt | Portuguese |
| ms | Malay |
| tl | Filipino |
| id | Indonesian |
| nl | Dutch |
| th | Thai |
| no | Norwegian |
| ca | Catalan |
| bn | Bengali |
| sr | Serbian |
| yue | Cantonese |
| hi | Hindi |
| tr | Turkish |
| pl | Polish |
| uk | Ukrainian |
| fa | Persian |
| ur | Urdu |
| sv | Swedish |
| da | Danish |
| fi | Finnish |
| cs | Czech |
| hu | Hungarian |
| ro | Romanian |
| el | Greek |
| bg | Bulgarian |
| hr | Croatian |
| sk | Slovak |
| sl | Slovenian |
| et | Estonian |
| lv | Latvian |
| lt | Lithuanian |
| bs | Bosnian |
| mk | Macedonian |
| is | Icelandic |
| sw | Swahili |
| ta | Tamil |
| te | Telugu |
| ml | Malayalam |
| kn | Kannada |
| gu | Gujarati |
| mr | Marathi |
| pa | Punjabi |
| km | Khmer |
| lo | Lao |
| my | Burmese |
| mn | Mongolian |
| ne | Nepali |
| he | Hebrew |
| az | Azerbaijani |
| kk | Kazakh |
| uz | Uzbek |
| ky | Kyrgyz |
| af | Afrikaans |
| am | Amharic |
| as | Assamese |
| ast | Asturian |
| be | Belarusian |
| ceb | Cebuano |
| cy | Welsh |
| ff | Fula |
| ga | Irish |
| gl | Galician |
| ha | Hausa |
| hy | Armenian |
| ig | Igbo |
| jv | Javanese |
| ka | Georgian |
| kea | Kabuverdianu |
| ku | Kurdish |
| lb | Luxembourgish |
| lg | Ganda |
| ln | Lingala |
| luo | Luo |
| mi | Maori |
| mt | Maltese |
| nso | Northern Sotho |
| ny | Nyanja |
| oc | Occitan |
| or | Odia |
| ps | Pashto |
| sd | Sindhi |
| sn | Shona |
| so | Somali |
| tg | Tajik |
| umb | Umbundu |
| wo | Wolof |
| xh | Xhosa |
| zu | Zulu |
Target Languages (target_language)
| Code | Language |
|---|---|
| zh | Chinese |
| en | English |
| ja | Japanese |
| ko | Korean |
| ru | Russian |
| de | German |
| fr | French |
| ar | Arabic |
| es | Spanish |
| it | Italian |
| vi | Vietnamese |
| pt | Portuguese |
| id | Indonesian |
| ms | Malay |
| tl | Filipino |
| nl | Dutch |
| th | Thai |
| tr | Turkish |
| pl | Polish |
| uk | Ukrainian |
| sv | Swedish |
| cs | Czech |
| el | Greek |
| hi | Hindi |
| fi | Finnish |
| da | Danish |
| no | Norwegian |
| hu | Hungarian |
| ro | Romanian |
| sk | Slovak |
| hr | Croatian |
| bg | Bulgarian |
| sr | Serbian |
| ca | Catalan |
| fa | Persian |
| ta | Tamil |
| bn | Bengali |
| af | Afrikaans |
| hy | Armenian |
| as | Assamese |
| az | Azerbaijani |
| be | Belarusian |
| bs | Bosnian |
| ceb | Cebuano |
| ny | Nyanja |
| et | Estonian |
| gl | Galician |
| ka | Georgian |
| gu | Gujarati |
| ha | Hausa |
| he | Hebrew |
| is | Icelandic |
| ga | Irish |
| jv | Javanese |
| kn | Kannada |
| kk | Kazakh |
| ky | Kyrgyz |
| lv | Latvian |
| ln | Lingala |
| lt | Lithuanian |
| lb | Luxembourgish |
| mk | Macedonian |
| ml | Malayalam |
| mr | Marathi |
| ne | Nepali |
| ps | Pashto |
| pa | Punjabi |
| sd | Sindhi |
| sl | Slovenian |
| so | Somali |
| sw | Swahili |
| te | Telugu |
| ur | Urdu |
| cy | Welsh |
