Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.heygen.com/llms.txt

Use this file to discover all available pages before exploring further.

Prerequisites

A Digital Twin avatar_id (type: digital_twin). Use GET /v3/avatars/looks?avatar_type=digital_twin to find yours.
A voice_id for the voice you want. Use GET /v3/voices to browse available voices.

Step 1 — Find your Digital Twin

List your private Digital Twin looks to get the avatar_id:
curl -X GET "https://api.heygen.com/v3/avatars/looks?avatar_type=digital_twin&ownership=private" \
  -H "x-api-key: YOUR_API_KEY"
From the response, copy the id field of the look you want. This is your avatar_id.

Step 2 — Choose a rendering engine

HeyGen v3 supports two rendering engines for Digital Twins. You select the engine via the engine object in your video creation request.
EngineKeyDefault?Quality
Avatar IVavatar_ivYes — used when engine is omittedStandard, widely supported
Avatar Vavatar_vNo — must be explicitly requestedHigher quality, cross-reference-driven animation
Before requesting Avatar V, check the supported_api_engines array on the avatar look via GET /v3/avatars/looks/{look_id}. If "avatar_v" is not listed, the request will be rejected. See Avatar Models for full details.

Step 3 — Create the video

Send a POST request to /v3/videos with type: "avatar", your Digital Twin ID, a script, and a voice.

Using Avatar IV (default)

Omit the engine field or pass {"type": "avatar_iv"} — Avatar IV is the default:
curl -X POST "https://api.heygen.com/v3/videos" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "avatar",
    "avatar_id": "YOUR_DIGITAL_TWIN_LOOK_ID",
    "script": "Hello! I am your Digital Twin. This video was generated entirely through the HeyGen API.",
    "voice_id": "YOUR_VOICE_ID",
    "title": "My First Digital Twin Video",
    "resolution": "1080p",
    "aspect_ratio": "16:9"
  }'

Using Avatar V (higher quality)

Pass {"type": "avatar_v"} in the engine field to request cross-reference-driven animation:
curl -X POST "https://api.heygen.com/v3/videos" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "avatar",
    "avatar_id": "YOUR_DIGITAL_TWIN_LOOK_ID",
    "script": "Hello! I am your Digital Twin.",
    "voice_id": "YOUR_VOICE_ID",
    "title": "My Digital Twin — Avatar V",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "engine": { "type": "avatar_v" }
  }'
motion_prompt and expressiveness are Avatar IV-only parameters. Do not include them when using Avatar V — they are not supported and will cause a validation error.

Step 4 — Poll for completion

Video generation is asynchronous. Poll GET /v3/videos/{video_id} until status is completed:
curl -X GET "https://api.heygen.com/v3/videos/YOUR_VIDEO_ID" \
  -H "x-api-key: YOUR_API_KEY"

Status values

StatusMeaning
pendingQueued for processing
processingVideo is being generated
completedReady — video_url is available
failedSomething went wrong — check failure_message
Once completed, the response includes a video_url with a presigned download link.

Full example

import requests
import time

API_KEY = "YOUR_API_KEY"
BASE = "https://api.heygen.com"
HEADERS = {"x-api-key": API_KEY, "Content-Type": "application/json"}

# 1. Create the video (Avatar V — swap engine for {"type": "avatar_iv"} or omit for default)
resp = requests.post(f"{BASE}/v3/videos", headers=HEADERS, json={
    "type": "avatar",
    "avatar_id": "YOUR_DIGITAL_TWIN_LOOK_ID",
    "script": "Welcome to our product demo. Let me walk you through the new features.",
    "voice_id": "YOUR_VOICE_ID",
    "resolution": "1080p",
    "aspect_ratio": "16:9",
    "engine": {"type": "avatar_v"}  # omit entirely to use Avatar IV (default)
})
video_id = resp.json()["data"]["video_id"]
print(f"Video created: {video_id}")

# 2. Poll until done
while True:
    status_resp = requests.get(f"{BASE}/v3/videos/{video_id}", headers=HEADERS)
    data = status_resp.json()["data"]
    print(f"Status: {data['status']}")
    if data["status"] == "completed":
        print(f"Download: {data['video_url']}")
        break
    elif data["status"] == "failed":
        print(f"Error: {data.get('failure_message')}")
        break
    time.sleep(10)

Optional parameters

ParameterTypeEngineDescription
titlestringBothDisplay name in the HeyGen dashboard
resolutionstringBoth4k, 1080p, or 720p
aspect_ratiostringBoth16:9 or 9:16
engineobject{"type": "avatar_iv"} or {"type": "avatar_v"}. Defaults to Avatar IV when omitted
remove_backgroundbooleanBothRemoves the avatar background (twin must be trained with matting enabled)
backgroundobjectBothSet a solid color or image background
voice_settingsobjectBothAdjust speed (0.5–1.5), pitch (-50 to +50), and locale
motion_promptstringIV onlyNatural-language prompt controlling avatar body motion
expressivenessstringIV onlyhigh, medium, or low. Defaults to low
output_formatstringBothmp4 (default) or webm (transparent background / alpha channel)
callback_urlstringBothWebhook URL — receive a POST when the video is ready

Using webhooks instead of polling

Instead of polling, pass a callback_url when creating the video. HeyGen will send a POST request to that URL when the video completes or fails.
{
  "type": "avatar",
  "avatar_id": "YOUR_DIGITAL_TWIN_LOOK_ID",
  "script": "This video uses a webhook callback.",
  "voice_id": "YOUR_VOICE_ID",
  "callback_url": "https://your-server.com/webhooks/heygen"
}
Register a webhook endpoint via POST /v3/webhooks/endpoints and subscribe to avatar_video.success and avatar_video.fail events for production use.