Discord

Multimodal

Talking avatars

POST /v1/avatars/videos makes a video of a character speaking: you choose the character and what it says, we return the finished video. The character can be a catalog avatar (avatar_id, listed by GET /v1/avatars) or one of your own photos (image_url); the speech can be text (script + voice_id, spoken by a voice from GET /v1/avatars/voices — Arabic and 50+ other languages) or audio you provide (audio_url).

Different from lip sync: lip sync takes your picture or video and your audio and only re-times the mouth. Here the character can come from a catalog and the speech from text, so the length of the result is not known until the job finishes (see Billing). For a live, conversational avatar, see Live video.

Create a talking avatar video

import requests
          
          H = {"Authorization": "Bearer llmr_sk_live_..."}
          API = "https://videorouter.sh/api/v1"
          
          # 1. pick an avatar and a voice (voices are filterable by language)
          avatar = requests.get(f"{API}/avatars?type=photo_avatar&limit=5", headers=H).json()["data"][0]
          voice = requests.get(f"{API}/avatars/voices?language=Arabic", headers=H).json()["data"][0]
          
          # 2. create the job -- returns immediately; the finished video is POSTed to webhook_url
          requests.post(f"{API}/avatars/videos", headers=H, json={
              "avatar_id": avatar["id"],
              "voice_id": voice["id"],
              "script": "مرحباً بكم في هذا العرض التجريبي.",
              "resolution": "1080p",
              "webhook_url": "https://your-app.com/hooks/video",
          })
          
          # ...or poll it:  GET {API}/avatars/videos/{id}  -> {"status": "completed", "data": [{"url": ...}], "cost_usd": 0.16}

The job object is the same one GET /v1/videos/{id} returns — poll GET /v1/avatars/videos/{id}, or pass a webhook_url (or save a default under Settings → Webhooks) and we POST the finished job to you; see Webhooks. The finished job carries cost_usd.

Your own audio or photo

# bring your own audio instead of a script (e.g. TTS you already produced) -- billed on its real length
          requests.post(f"{API}/avatars/videos", headers=H, json={
              "avatar_id": avatar["id"],
              "audio_url": "https://example.com/voiceover.mp3",
          })
          
          # or animate one of your OWN photos (requires consent for the person shown)
          requests.post(f"{API}/avatars/videos", headers=H, json={
              "image_url": "https://example.com/portrait.jpg",
              "source_face_consent": True,
              "script": "Hello!", "voice_id": voice["id"],
          })

Parameters

ParameterTypeDescription
modelstringOptional, default heygen/avatar-iv.
avatar_id
or image_url
stringExactly one. avatar_id is an id from GET /v1/avatars. image_url is one photo of a person and requires source_face_consent: true (else 400 consent_required).
script + voice_id
or audio_url
stringExactly one. script is up to 5000 characters, spoken by voice_id (from GET /v1/avatars/voices). audio_url is a finished track, up to 10 minutes.
resolutionstring720p, 1080p (default) or 4k. 720p and 1080p cost the same.
aspect_ratiostring16:9 (default), 9:16, 4:5, 5:4, 1:1 or auto.
voice_settingsobjectScript mode only: speed 0.5–1.5, pitch −50…50, volume 0–1, locale (e.g. ar-SA).
webhook_urlstringOptional https URL for a completion webhook; see Webhooks.

Errors you can act on: 400 consent_required, 400 avatar_not_found (unknown avatar_id), 400 avatar_not_supported (the avatar is not available on this model), 402 insufficient_credits.

Avatars, voices and models

RouteReturns
GET /v1/avatarsCatalog avatars ready to use — id, name, type (photo_avatar or digital_twin), gender, orientation, preview image and video, and the default_voice_id that suits it. Filter with ?type=; page with ?limit= (1–50) and the returned next_token.
GET /v1/avatars/voicesVoices — id, name, language, gender, a preview_audio_url. Filter with ?language=Arabic (HeyGen’s spelling; “Multilingual” voices speak several) and ?gender=; page with ?limit= and next_token.
GET /v1/avatars/modelsValid model slugs with what each takes. Also listed by GET /v1/models?type=avatar.

All three are free to call. The catalog is cached for ten minutes.

Billing

You pay for the seconds of video produced. Because a script is spoken at the voice’s own pace, the length is only known when the job finishes: we hold an estimate when you submit (about 9 characters per second, slower for a reduced speed; an audio track is measured exactly), then settle the real duration and release the rest. A failed job costs nothing.

Avatar type720p / 1080p4K
Photo avatar, or your own photo$3.00 / minute$4.00 / minute
Digital twin$4.00 / minute$5.00 / minute

Rates are the provider’s list prices; our flat 2.5% platform fee is added on top. The hold is sized to the longest the script could plausibly run, so a script near the 5000-character limit needs a balance of roughly $35 free to submit — the actual charge is far lower.

Which models

ModelTakesNotes
heygen/avatar-ivcatalog avatar or one photo, plus script + voice or audioHeyGen Avatar IV. Studio avatars (Avatar III only) are not offered.
vidu/s1-avatar-offlineone photo, plus audioVidu S1, 540p/720p, $0.005/s. Same model as on /v1/lipsync.
fal/heygen-avatar4-image-to-videoone photo, plus audioHeyGen Avatar 4 via Fal, $0.10/s. Same model as on /v1/lipsync.

The two talking-photo models are accepted here as a single front door for everything avatar-shaped; /v1/lipsync keeps accepting them too. Limits: script ≤ 5000 characters, audio ≤ 10 minutes, a handful of jobs in flight per organization.