OmniHuman 2.0 Audio to Video API
bytedance/omnihuman-2.0/audio-to-videoOmniHuman 2.0 Audio to Video turns one character image and 4–300 seconds of speech or music into a 720p video, with lips, expression and gestures following the audio. The image keeps the character's look and framing, while an optional prompt adds camera moves and actions.
Drag and drop files, paste from clipboard, or provide a URL. Required. One JPEG, PNG or WebP character image.
1/1 files added
Drag and drop files, paste from clipboard, or provide a URL. Required. One WAV or MP3 file, 4–300 seconds, up to 15 MB.
1/1 files added
REST API
Quick Start
Make your first OmniHuman 2.0 request in three steps; the example sends an image, a voice track and a short camera prompt.
Connect to the Vidgo API
Create an API key, keep it on your server, and send it in the Authorization header as a Bearer token.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Submit one generation task
Run the short example with one image and one driving audio file. The prompt is optional.
curl --request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "bytedance/omnihuman-2.0/audio-to-video",
"input": {
"image_urls": [
"https://cdn.vidgo.ai/apis/models/bytedance/omnihuman-2.0/audio-to-video/v1/01/input-01.png"
],
"audio_url": "https://cdn.vidgo.ai/apis/models/bytedance/omnihuman-2.0/audio-to-video/v1/02/input-02.mp3",
"prompt": "She speaks warmly to the camera, nodding and gesturing with her right hand. The camera slowly pushes in from a medium shot to a close-up."
}
}'Wait for the result
Use the returned task_id to check the same task until it reaches finished or failed. On success, read data.files[].file_url.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll about every 2 seconds while the status is not_started or running. Stop on finished or failed; on success, read data.files[].file_url. For long-running jobs, increase the interval gradually, or add callback_url to the submit request to receive the final result asynchronously.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "8TBISH3H90QQBZ5X",
"status": "not_started",
"created_time": "2026-11-05T07:04:47"
}
}{
"code": 200,
"data": {
"task_id": "8TBISH3H90QQBZ5X",
"status": "finished",
"files": [
{
"file_url": "https://cdn.vidgo.ai/apis/models/bytedance/omnihuman-2.0/audio-to-video/v2/01/output-01.mp4",
"file_type": "video"
}
],
"created_time": "2026-11-05T07:04:47",
"error_message": null,
"progress": 100
}
}Complete runnable example
Open this after the three-step flow is clear. It combines submission, polling, terminal-state handling, and result extraction in one script.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "bytedance/omnihuman-2.0/audio-to-video",
"input": {
"image_urls": [
"https://cdn.vidgo.ai/apis/models/bytedance/omnihuman-2.0/audio-to-video/v1/01/input-01.png"
],
"audio_url": "https://cdn.vidgo.ai/apis/models/bytedance/omnihuman-2.0/audio-to-video/v1/02/input-02.mp3",
"prompt": "She speaks warmly to the camera, nodding and gesturing with her right hand. The camera slowly pushes in from a medium shot to a close-up."
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
while true; do
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep 2
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneRequest Parameters
model and callback_url belong at the request root; generation parameters belong inside input.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| model | string | Yes | — | Fixed to bytedance/omnihuman-2.0/audio-to-video. |
| callback_url | string (URL) | No | — | A public HTTP(S) URL for receiving task completion notifications. |
| input | object | Yes | — | Generation parameters: one image in image_urls and one driving audio file in audio_url, plus an optional prompt. Video length follows the audio. |
| input.image_urls | string[] | Yes | — | Exactly one public HTTP(S) URL of the character or portrait image. |
| input.audio_url | string | Yes | — | Public HTTP(S) URL of a WAV or MP3 file, up to 15 MB and 4–300 seconds long. The server reads its duration. |
| input.prompt | string | No | — | Optional guidance for camera movement, actions and scene elements. |
Response Fields
Submission returns the task identity immediately. Status responses add progress, output files, or a failure message as the task advances.
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code. Successful responses use 0 or 200. |
| message | string | Human-readable response or error message when present. |
| data.task_id | string | Task identifier used in the status endpoint path. |
| data.status | string | Current state: not_started, running, finished, or failed. |
| data.created_time | string | Task creation time in date-time format. |
| data.progress | number | Completion percentage when the provider reports progress. |
| data.files[] | array | Generated output files returned after a successful task. |
| data.files[].file_url | string | Public URL of the generated video. |
| data.files[].file_type | string | Generated file type, such as video. |
| data.files[].watermark_url | string | null | Watermarked output URL when one is available. |
| data.error_message | string | null | Failure detail when status is failed. |
Task Lifecycle
Treat not_started and running as non-terminal states. finished and failed are terminal alternatives; stop polling when either is returned.
not_startedThe task has been accepted and is queued to start.
runningThe video is being generated. Continue polling the status endpoint.
finishedThe task is complete. Read the video URL from data.files[].file_url.
failedGeneration failed. Read data.error_message for details and stop polling.
Polling and Errors
- Authentication401 indicates a missing or invalid Bearer API Key. Check your key in the dashboard before retrying.
- Validation400 indicates invalid parameters. Check that image_urls holds one URL and that audio_url is a reachable WAV or MP3 of 4–300 seconds and up to 15 MB.
- Polling intervalPoll the status every 2 seconds. For longer tasks, use exponential backoff to gradually increase the interval to 5 seconds.
- Terminal statesPoll only while the status is not_started or running. Stop immediately on finished or failed.
- Callback optionProvide callback_url to receive an automatic notification when generation finishes, without continuous polling.
Model Specifications
| Specification | Value | Description |
|---|---|---|
| Model | bytedance/omnihuman-2.0/audio-to-video | Model identifier for asynchronous OmniHuman 2.0 audio-driven video generation. |
| Input mode | 1 image + 1 audio + optional prompt | The audio drives lips, expression and gestures. |
| Audio | WAV or MP3, 4–300 s, ≤15 MB | Video length follows the audio. |
| Resolution | 720p | Framing follows the input image. |
| Billing | Hold: audio seconds × 21 credits | Settled against the final charge after completion; the difference is refunded. |
Related Models
OmniHuman 2.0 Audio to Video API FAQ
What is the OmniHuman 2.0 Audio to Video API?
OmniHuman 2.0 Audio to Video is a ByteDance model for audio-driven video generation from a single image. It turns one character image and 4–300 seconds of speech or music into a 720p video in which lips, expression and gestures follow the audio. The image fixes the character's appearance and framing, while an optional prompt adds camera movement, actions and scene elements. You can call it programmatically or try it from the playground above.
How long can the audio be for OmniHuman 2.0 Audio to Video?
4 to 300 seconds, as a WAV or MP3 file of up to 15 MB. The video length follows the audio, so there is no separate duration setting.
How are credits handled for OmniHuman 2.0 Audio to Video?
When you submit, audio seconds × 21 credits are held from your balance, so 60 seconds of audio holds 1,260 credits. After the task finishes, the hold is settled against the final charge for the generated video and any difference is refunded.
What does the prompt control in OmniHuman 2.0 Audio to Video?
The optional prompt guides camera movement, actions and added scene elements. Lip shapes, emotion and timing come from the audio.
Can OmniHuman 2.0 Audio to Video animate animals or cartoons?
Yes. Besides people it handles animals, cartoon and anime characters, 3D figures and stylised art, as well as images with several people.
What resolution does OmniHuman 2.0 Audio to Video produce?
It outputs 720p video, with framing that follows the input image, so crop the image to the shape you want to publish.
Which audio gives the best OmniHuman 2.0 lip sync?
Clear speech or vocals with little background noise and no long silences. Trim the file to the part you need before uploading.
Can OmniHuman 2.0 Audio to Video sing as well as speak?
Yes. A song or vocal track drives the character's singing, with expression and body movement following the music's rhythm.















