Skip to content

How to Create a Digital Human

Generate a talking avatar video from a portrait image and an audio track. The avatar's lip movements and expressions are synchronized to the audio.

Quick Start

These tasks are slow — submit asynchronously and poll:

bash
curl -X POST "https://api.get3w.com/v1/bytedance/omnihuman-1.5/digital-human" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://your-cdn.com/portrait.png",
    "audio_url": "https://your-cdn.com/speech.mp3"
  }'
python
import time
import requests

headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

task = requests.post(
    "https://api.get3w.com/v1/bytedance/omnihuman-1.5/digital-human",
    headers=headers,
    json={
        "image_url": "https://your-cdn.com/portrait.png",
        "audio_url": "https://your-cdn.com/speech.mp3"
    }
).json()

while True:
    data = requests.get(
        f"https://api.get3w.com/v1/requests/{task['id']}",
        headers=headers
    ).json()

    if data["status"] == "completed":
        print(data["outputs"][0])
        break
    if data["status"] == "failed":
        print(f"Failed ({data['code']}):", data["error"])
        break

    time.sleep(10)

Available Models

SlugNotes
bytedance/omnihuman-1.5/digital-humanExpressive full-body motion
kling/kling-avatar-2/digital-humanstandard and pro channels

Complete Workflow

Generate the speech first, then feed its output URL into the digital human model:

python
import time
import requests

headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

speech = requests.post(
    "https://api.get3w.com/v1/elevenlabs/eleven-3/text-to-speech?sync=true",
    headers=headers,
    json={"text": "Hello, welcome to our product demo."}
).json()
audio_url = speech["outputs"][0]

task = requests.post(
    "https://api.get3w.com/v1/bytedance/omnihuman-1.5/digital-human",
    headers=headers,
    json={
        "image_url": "https://your-cdn.com/portrait.png",
        "audio_url": audio_url
    }
).json()

while True:
    data = requests.get(
        f"https://api.get3w.com/v1/requests/{task['id']}",
        headers=headers
    ).json()
    if data["status"] in ("completed", "failed"):
        print(data["status"], data.get("outputs") or data.get("error"))
        break
    time.sleep(10)

Output URLs from one task can be passed straight into the next — no re-upload needed.

Tips

  • Front-facing portrait — Clear, well-lit, face unobstructed
  • Clean audio — Background noise degrades lip sync accuracy
  • Neutral starting expression — Gives the model more room to animate
  • Start short — These are among the most expensive run types; validate with a short clip first
  • Publicly reachable URLs — Both inputs are fetched by the provider; unreachable URLs fail with code 1402

Next Steps

Released under the MIT License.