OmniHuman 2.0 API
ByteDance's second-generation audio-driven human video: a portrait speaks or sings to the audio with camera and body movement, at native 720p.
OmniHuman 2.0 is a talking avatar video model from ByteDance, available on OttoPort's OpenAI-compatible API as the model ID omnihuman-2.0 at $0.131 / second of audio as of 2026-10-17.
Provider
ByteDance
Price
$0.131 / second of audio
Model ID
omnihuman-2.0
Type
talking avatar video model
Create with OmniHuman 2.0
avatarOmniHuman 2.0 API pricing
What OttoPort bills for OmniHuman 2.0, and what that works out to per unit. Rates are read from the same catalog the gateway meters against, and were current on 2026-10-17.
| Per second | $0.131 | of audio, rounded up to the whole second |
|---|---|---|
| 10 seconds of audio | $1.31 | |
| 30 seconds of audio | $3.93 | |
| 60 seconds of audio | $7.86 | the longest accepted |
No subscription and no minimum — OttoPort bills prepaid credits against usage. See the full rate card.
Call OmniHuman 2.0 in three lines
Send "model": "omnihuman-2.0" to POST https://ottoport.ai/api/v1/videos/generations with an OttoPort key. No ByteDance account, no waitlist, no separate SDK.
curl https://ottoport.ai/api/v1/videos/generations \
-H "Authorization: Bearer $OTTOPORT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "omnihuman-2.0",
"image_url": "https://example.com/portrait.png",
"audio_url": "https://example.com/voice.mp3",
"prompt": "speaks warmly to camera, small natural gestures"
}'import uuid, requests
job = requests.post(
"https://ottoport.ai/api/v1/videos/generations",
headers={"Authorization": "Bearer " + API_KEY, "Idempotency-Key": str(uuid.uuid4())},
json={
"model": "omnihuman-2.0",
"image_url": "https://example.com/portrait.png",
"audio_url": "https://example.com/voice.mp3",
"prompt": "speaks warmly to camera, small natural gestures",
},
).json()
# A job, like any video: poll it for the video's URL, or pass webhook_url.
# It runs, and bills, as long as the audio.
print(job["id"], job["status"])const res = await fetch("https://ottoport.ai/api/v1/videos/generations", {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
model: "omnihuman-2.0",
image_url: "https://example.com/portrait.png",
audio_url: "https://example.com/voice.mp3",
prompt: "speaks warmly to camera, small natural gestures",
}),
});
// A job, like any video: poll it for the video's URL, or pass webhook_url.
const job = await res.json();
console.log(job.id, job.status);Before you start
- 1. Create a key at /api-keys.
- 2. Top up credits — the smallest pack is $25.
- 3. Paste the request. It returns a job ID; poll it or pass a webhook_url.
Full reference at /docs, or drive it from an agent with the MCP server and CLI.
Request parameters
The body POST https://ottoport.ai/api/v1/videos/generations accepts for OmniHuman 2.0.
| Field | Type | Required | Notes |
|---|---|---|---|
| model | string | Yes | Always omnihuman-2.0 for OmniHuman 2.0. |
| image_url | string | Yes | The portrait to animate: a public PNG or JPEG of one person, face clearly visible. |
| audio_url | string | Yes | The speech or song, a public MP3 or WAV of 4–60 seconds. The video runs, and bills, as long as this audio. |
| prompt | string | No | Optional direction for expression, gesture and camera. |
| webhook_url | string | No | Called when the job settles, so you need not poll. |
| webhook_secret | string | No | Signs the webhook so you can verify it came from OttoPort. |
OmniHuman 2.0 direct vs through OttoPort
OmniHuman 2.0 is the same model either way — what changes is how many accounts, keys, and integrations you carry to reach it.
| ByteDance direct | Via OttoPort | |
|---|---|---|
| Accounts and keys | A ByteDance account, plus one more for every other model you add | One OttoPort account and one key for the whole catalog |
| Request shape | ByteDance's own SDK and response format | OpenAI-compatible — point baseURL at OttoPort and change the model string |
| Switching models | A new integration per provider | Replace omnihuman-2.0 with any other model ID in the catalog |
| Billing | A separate invoice and contract per provider | Prepaid credits, no subscription, one usage ledger |
| Provider outages | Your call fails | Configured backup routes are tried in order on provider failure |
Use a sharp, front-facing portrait with the mouth visible.
Clean speech with little background noise syncs best.
The video runs as long as the audio, and that length is what bills.
OmniHuman 2.0 API questions
Cost, keys, and model IDs for OmniHuman 2.0 on OttoPort.
How much does the OmniHuman 2.0 API cost?
On OttoPort, OmniHuman 2.0 costs $0.131 / second of audio as of 2026-10-17. For scale, 10 seconds of audio: $1.31. Billing is prepaid usage with no subscription and no minimum, and the current rate is always published at ottoport.ai/pricing.
How do I get an OmniHuman 2.0 API key?
You do not need a ByteDance key. Create an OttoPort account, generate a key at ottoport.ai/api-keys, and send it as "Authorization: Bearer <key>" to POST https://ottoport.ai/api/v1/videos/generations with "model": "omnihuman-2.0". The same key reaches every other model in the catalog.
What is the model ID for OmniHuman 2.0?
The OttoPort model ID for OmniHuman 2.0 is omnihuman-2.0. Pass it as the model field on POST https://ottoport.ai/api/v1/videos/generations, or list it programmatically from GET https://ottoport.ai/api/v1/models.
What does OmniHuman 2.0 take, and how long is the video?
A portrait as image_url and a voice track as audio_url, plus an optional prompt. The person in the portrait speaks or sings the audio, and the video runs exactly as long as it. You are billed $0.131 / second of audio, measured by OttoPort before the job starts — there is no duration to set.
Is OmniHuman 2.0 generation synchronous?
No. POST https://ottoport.ai/api/v1/videos/generations returns a job ID immediately. Poll GET https://ottoport.ai/api/v1/videos/generations/{id} for status, or pass webhook_url and webhook_secret and OttoPort will call you when the job settles. You are billed per second of audio, so a failed job costs nothing.
Do I need a ByteDance account to use OmniHuman 2.0?
No. OttoPort connects to ByteDance on your behalf, so one OttoPort account covers OmniHuman 2.0 and every other model in the catalog — no per-provider contracts, keys, or invoices.
Other video generation models on the same API
Same endpoint, same key — swapping model is a one-string change from omnihuman-2.0.
Gemini Omni 1.1 Flash API
$0.138 / second
Gemini Omni Flash API
$0.156 / second
Wan 3.0 Text to Video API
Alibaba
$0.20 / second
FLUX 3 API
Black Forest Labs
$0.213 / second
Seedance 2.5 API
ByteDance
$0.35 / second
MiniMax H3 API
MiniMax
$0.163 / second
Browse the full catalog — every model with its provider and per-unit price.