Short-form talking-head content — a founder update, a product walkthrough, a UGC-style ad read — usually means booking a person, a mic, and an editing pass. heygen-avatar-v on hiapi collapses that into one API call: send a script or an audio file, get back a lip-synced avatar clip with natural idle motion and a subtitle track, ready to drop into a short-form feed. This walks through the actual /v1/tasks workflow, a real generated clip, the constraints worth knowing before you build a pipeline around it, and live pricing pulled from hiapi's /api/pricing. If you're after prompt-level styling tricks for the avatar itself, heygen-avatar-v prompt recipes covers that ground — this piece is about wiring the model into a repeatable short-form video pipeline.
What heygen-avatar-v Actually Outputs
heygen-avatar-v is a digital-human video model, not a text-to-video generator in the Sora/Kling sense — it drives a preset HeyGen avatar with either a text script or an uploaded audio file, and returns a video where the avatar's mouth is lip-synced to the speech, with small continuous motion (blinking, subtle head movement, shoulder shift) so it doesn't read as a static portrait. That "it keeps moving even when idle" behavior is exactly what separates a usable short-form clip from an obviously-fake talking photo.
Two inputs drive the model, and they're mutually exclusive — you send one or the other:
prompt— a text script; hiapi's TTS reads it and drives the lip-syncaudio_url— a public URL to a pre-recorded voice track (your own VO, a cloned voice, whatever) which drives the lip-sync instead
There's no duration field. Clip length is entirely a function of how long the script or audio runs — a 40-word line produces a shorter clip than a 200-word one. That matters for cost planning, covered below.
Optional fields round out the styling: avatar (pick from HeyGen's preset library), voice (used only with prompt, ignored with audio_url), aspect_ratio (9:16 for Reels/TikTok/Shorts, 16:9, 1:1), resolution, background (solid color or scene — but see the catch below), caption (generates a subtitle track), and output_format (mp4 or webm, the latter with a transparent background for compositing over your own scene).
A Real Clip: Script In, Captioned Avatar Video Out
Here's an actual heygen-avatar-v output — an avatar delivering a scripted line, with visible idle motion between phrases and a synced caption track:
Notice what's not happening: the avatar isn't frozen between sentences, and the captions track the speech instead of being pasted on as an afterthought. That combination — motion continuity plus timed captions — is the whole pitch for using this model over a static avatar image with a voiceover slapped under it in your editor.
The Catch: Two Things That Will Bite a First Pipeline
caption gives you a subtitle sidecar, not hardsubs. Setting caption: true returns a synced .srt file alongside the video output — it does not burn text into the video frames. If you want on-screen caption text (the look most short-form platforms use), you need a separate burn-in pass with the .srt file (ffmpeg -i clip.mp4 -vf subtitles=captions.srt output.mp4, or your platform's native caption import). Treat the API's "captions" as data, not a rendered visual.
background only applies to illustrated avatars, not filmed ones. HeyGen's avatar library mixes photorealistic filmed avatars with illustrated/animated ones. The background parameter successfully swaps the scene behind illustrated avatars, but filmed avatars keep their original recorded backdrop regardless of what you pass — the model won't key it out. If your pipeline assumes every avatar accepts a background override, test the specific avatar ID you're using before assuming it'll composite the way you expect. output_format: webm (transparent) is the reliable route for filmed avatars you want to place over your own background.
Cost: It's Metered Per Second of Output, Not Per Call
Per hiapi's live /api/pricing, heygen-avatar-v bills at $0.15 per second of output video — a flat rate regardless of resolution or aspect ratio. Since there's no duration input, your actual cost is set by how long your script or audio runs:
| Script length (approx.) | Output duration | Cost |
|---|---|---|
| Short hook line | ~5s | $0.75 |
| One short-form beat | ~10s | $1.50 |
| Multi-sentence pitch | ~20s | $3.00 |
| Full 30-second ad read | ~30s | $4.50 |
Because cost scales with speech length and not with a param you set upfront, the practical move is to time your script (read it aloud, or run it through a TTS length estimator) before submitting the task, rather than discovering the bill after the clip renders.
The Pipeline: Submit, Poll, Download Before It Expires
heygen-avatar-v runs on hiapi's async /v1/tasks endpoint — the same create-then-poll shape as every other task-based model on the platform. One detail specific to this workflow: the task moves through an archiving step between handling and success while the platform finalizes the video + caption sidecar, so don't treat archiving as a terminal state in your poll loop.
import time
import requests
API_KEY = "sk-your-hiapi-key" # from https://www.hiapi.ai/en/dashboard/api-keys
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
def create_avatar_video(script: str, avatar: str, aspect_ratio: str = "9:16") -> str:
payload = {
"model": "heygen-avatar-v",
"input": {
"prompt": script,
"avatar": avatar,
"aspect_ratio": aspect_ratio,
"caption": True,
},
}
resp = requests.post(BASE, headers=HEADERS, json=payload, timeout=60)
resp.raise_for_status()
return resp.json()["data"]["taskId"]
def wait_for_video(task_id: str, timeout_s: int = 300, poll_every: int = 5) -> dict:
deadline = time.time() + timeout_s
while time.time() < deadline:
resp = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30)
resp.raise_for_status()
task = resp.json()["data"]
status = task["status"]
if status == "success":
return task["output"] # [{"url": "...mp4"}, {"url": "...srt"}] — download both, now
if status == "failed":
err = task.get("error", {})
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
# "handling" and "archiving" are both non-terminal — keep polling
time.sleep(poll_every)
raise TimeoutError(f"task {task_id} did not finish in {timeout_s}s")
if __name__ == "__main__":
task_id = create_avatar_video(
script="Here's the thirty-second version of what we shipped this week.",
avatar="your-avatar-id",
)
outputs = wait_for_video(task_id)
print("outputs:", outputs)
Two operational notes that aren't optional at scale:
- Download immediately. Like every hiapi task output, the returned URLs carry an
expireAtand are not meant for long-term linking — pull the bytes (video and.srt) to your own storage the moment the task succeeds. - Don't send a bare minimal payload "just to check the schema." Because only
promptoraudio_urlis strictly required and everything else defaults silently, a payload with just{"prompt": "test"}doesn't 400 — it dispatches a real, billable render. Validate your field names against the docs or a 4xx response from an intentionally-invalid value, not by omitting fields against a real endpoint.
FAQ
Can I use my own voice instead of hiapi's TTS?
Yes — pass audio_url instead of prompt with a public URL to your recording, and the avatar lip-syncs to that audio track instead of synthesizing speech from text.
Does the caption option burn subtitles into the video?
No. caption: true returns a separate .srt file synced to the output video's audio. If you want on-screen caption text, burn it in yourself as a post-processing step.
Can I control how long the clip is?
Not directly — there's no duration parameter. Output length is determined by the length of your script (for prompt) or the length of your audio file (for audio_url).
Why didn't the background I specified show up?
background only works on illustrated/animated avatars in HeyGen's library. Filmed, photorealistic avatars keep their original recorded backdrop; use output_format: webm for a transparent output you can composite yourself instead.
What resolution and aspect ratios does it support?
Up to 4K, with 9:16, 16:9, and 1:1 aspect ratio options — covering vertical short-form feeds through to widescreen and square placements.
Takeaways
Building a short-form avatar pipeline on hiapi comes down to a few concrete facts, not guesswork: cost is $0.15 per second of output (so time your script before submitting, not after), the caption output is an .srt sidecar you burn in yourself, background swaps only work on illustrated avatars, and your poll loop needs to treat archiving as non-terminal alongside handling. Check current numbers on hiapi's pricing page before hardcoding a budget, and see the model page for the full field reference. If you're ready to build, grab an API key from the dashboard and start with a short script — five seconds of output is enough to confirm your avatar, aspect ratio, and caption handling all work before you scale up to a full batch.








