HeyGen Avatar IV turns one portrait photo plus a script (or your own audio) into an MP4 of that person talking. On HiAPI it costs $0.15 per second of video, and your first API call takes about five minutes from key to finished file.
HeyGen Avatar IV is live on HiAPI. Open the model page, upload a photo, and generate in the browser before you write a line of code.
Here is what one photo and one sentence produce. This 9-second explainer started from a single sweater portrait:
1080p, 16:9, 9 seconds, voice Cute Chloe - Friendly. The sweater, hairstyle and room from the photo stay intact while her lips, blinks and small nods follow the voice.
The script:
Hi, I'm Lin. With one photo and a short script, I can present your product or record a lesson, with natural lip-sync and expressions.
Generate with this script → The script is pre-filled; upload your own photo to generate.
What is HeyGen Avatar IV good for?
Use it when you have a photo and want that specific person on screen. Common jobs:
- Product explainers and social clips: one photo, a new script per selling point, a batch of short videos.
- Courses and training: a teacher's photo once, then only a script for each lesson.
- Company updates and support videos: a consultant, doctor or store manager keeps the same face while the message changes.
- Illustrated and 3D characters: any character with a clear face can talk.
If you would rather pick from preset presenters, or need a transparent background, captions or 4K, go with HeyGen Avatar V. The price is the same.
Try it on the model page first
- Click Generate with this script above; the script fills in automatically.
- Upload a front-facing, evenly lit photo of one person.
- Choose 1080p and 16:9. Leave the voice empty to use the default, Warm Pro Narrator.
- Hit generate, preview the result, and download it.
A 10-second clip costs $1.50, and $10 covers about 66 seconds of video: plenty to compare a few photos and voices.
What you need before calling the API
- An API key. Create one in the dashboard and send it as
Authorization: Bearer sk-.... - A public HTTPS URL for the photo. The API reads the image from a link, so host it on your own storage or CDN first. Front-facing single-person shots with even light, an unobstructed face and a relaxed closed mouth give the steadiest results.
- A script or an audio file. A script is read aloud by the voice you pick; an
audio_urlmakes the lips follow your own recording. Send one of the two.
Create your first task with cURL
The photo URL below works as-is. Swap in your key and run it:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "heygen-avatar-iv",
"input": {
"image_url": "https://static.hiapi.ai/blog/heygen-avatar-iv/portrait-landscape.jpg",
"prompt": "Hi, I'\''m Lin. With one photo and a short script, I can present your product or record a lesson, with natural lip-sync and expressions.",
"voice": "Cute Chloe - Friendly",
"resolution": "1080p",
"aspect_ratio": "16:9"
}
}'
The task ID comes back in data.taskId:
{"code":200,"data":{"taskId":"tk-hiapi-01M4HS6EXQSHBJETX84MKTXYCF"},"message":"success"}
You never send a duration. With a script, length follows the words and the voice's pace; with audio, the video runs as long as the recording.
Get the finished video
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01M4HS6EXQSHBJETX84MKTXYCF \
-H "Authorization: Bearer sk-YOUR_KEY"
Once data.status is success, take the item in data.output whose type is video. Its url is the MP4, and expireAt tells you when the link lapses:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-01M4HS6EXQSHBJETX84MKTXYCF",
"status": "success",
"model": "heygen-avatar-iv",
"output": [
{
"type": "video",
"url": "https://temp.hiapi.ai/7c6ttvrbpt/01M4HS6EXQSHBJETX84MKTXYCF-0.mp4",
"artifactId": "78591",
"expireAt": 1787623851
}
]
},
"message": "success"
}
Full Python example: create, poll, download
import time
import requests
API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-YOUR_KEY"}
payload = {
"model": "heygen-avatar-iv",
"input": {
"image_url": "https://static.hiapi.ai/blog/heygen-avatar-iv/portrait-landscape.jpg",
"prompt": "Hi, I'm Lin. With one photo and a short script, I can present your product or record a lesson, with natural lip-sync and expressions.",
"voice": "Cute Chloe - Friendly",
"resolution": "1080p",
"aspect_ratio": "16:9",
},
}
resp = requests.post(API, headers=HEADERS, json=payload, timeout=30)
task_id = resp.json()["data"]["taskId"]
print("task:", task_id)
while True:
data = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
if data["status"] in ("success", "fail"):
break
time.sleep(8)
if data["status"] == "success":
video_url = next(o["url"] for o in data["output"] if o["type"] == "video")
with open("avatar-iv.mp4", "wb") as f:
f.write(requests.get(video_url, timeout=120).content)
print("saved avatar-iv.mp4")
else:
print(data.get("error"))
Parameters
| Parameter | Required | Default | What it does |
|---|---|---|---|
image_url | Yes | — | Public HTTPS link to a portrait with a clear face |
prompt | One of two | — | The script, up to 5,000 characters, English or Chinese |
voice | No | Warm Pro Narrator | One of 102 preset voices; applies to scripts |
audio_url | One of two | — | Audio that drives the lips, up to 600 seconds |
resolution | No | 720p | 720p or 1080p, same price |
aspect_ratio | No | 16:9 | 16:9, 9:16, 4:5, 5:4, 1:1, or auto (keeps the photo's ratio) |
background | No | White | {"type": "color" or "image", "value": ...} fills empty space in the frame |
callback | No | — | {"url": "...", "when": "final"} pushes the task object when it finishes |
The schema is strict: a field outside this list, such as a duration carried over from another model, gets the request rejected before it queues:
{"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: <root>: additional properties 'duration' not allowed"}
The full list of 102 voices is in the API docs.
Script, audio and background in practice
Script-driven. Send prompt and voice to swap content in bulk. This vertical review used a 9:16 photo, so the output fills the frame edge to edge:
1080p, 9:16, 8 seconds, voice Andrew.
I've been using these new earbuds for a week. The noise canceling is super quiet, and the battery lasts all day. Follow me for more.
Generate with this script → The script is pre-filled; upload your own vertical photo and choose 9:16 to generate.
Audio-driven. Already have a voiceover, or want your own voice? Replace prompt and voice with audio_url, and the lips and pauses follow the recording.
Background. When the output ratio differs from the photo, background fills the extra space. Use {"type": "color", "value": "#F5EFE6"} for a flat color or {"type": "image", "value": "https://..."} for an image. Here a landscape teacher photo sits in a vertical frame with a chalkboard above and below:
1080p, 9:16, 11 seconds, voice Professor Dean, background set to a chalkboard image.
Hello everyone. Today we'll explain the Pythagorean theorem in five minutes. In a right triangle, the squares of the two legs add up to the square of the hypotenuse.
Generate with this script → The script is pre-filled; upload your own photo to generate.
Three things to set before going live
- Use a callback on the server. Add
"callback": {"url": "https://yourapp.com/webhook", "when": "final"}and HiAPI pushes the result once the task finishes, so you can drop polling. - POST each task once. Every
POST /v1/taskscreates and bills a new task. After a network timeout, check whether you saved ataskId; if you did, keep polling or wait for the callback. - Download right after success. Output links expire, so copy the MP4 to your own storage as soon as the task completes.
How is it billed?
$0.15 per second of output video, with 720p and 1080p at the same price, so set 1080p explicitly. HiAPI holds an amount based on the estimated length when the task is created, then charges the actual seconds and settles the difference automatically. Failed tasks are refunded in full.
| Video length | Price |
|---|---|
| 5 seconds | $0.75 |
| 10 seconds | $1.50 |
| 30 seconds | $4.50 |
| 60 seconds | $9.00 |
Cost tracks seconds only, so shorter scripts mean smaller bills. Three hundred 10-second clips a month come to $450; twenty 60-second lessons come to $180.
Lin's 9-second clip at the top cost $1.35. Generate with the same script → The script is pre-filled; upload your own photo to generate and see how long your version runs.
FAQ
Can the script be in Chinese?
Yes. prompt accepts English and Chinese, up to 5,000 characters.
Can I use my own voice?
Yes. Pass a recording as audio_url, up to 600 seconds, and the lips follow it.
Which photos work well? A front-facing photo of one person with even light, an unobstructed face and a relaxed closed mouth. Illustrated and 3D characters work too when the face is clear. For side profiles, masks, group shots or very small faces, switch to a closer portrait; a task that fails to detect a face is refunded in full.
My photo is landscape. How do I get a vertical video?
Set aspect_ratio to 9:16 and fill the top and bottom with background, as in the chalkboard example above.
How long does a video take? Generation is asynchronous, and longer scripts and higher resolutions take longer. Use a callback so the result arrives the moment it is ready.
Related reading
- HeyGen Avatar IV API pricing: cost per second, per clip and per month
- HeyGen Avatar IV vs HeyGen Avatar V: your photo or a preset presenter
- HeyGen Avatar IV prompt guide: scripts and photos that render well
- HeyGen Avatar IV API docs: every parameter and all 102 voices
Ready for your own? Grab a front-facing photo and generate with Lin's script →. The script is pre-filled; upload your own photo, choose 1080p and 16:9, and a 9-second clip costs $1.35.



