HeyGen API avatar ID and voice ID: where to find them
In HeyGen's v3 API, avatar_id is a look id from GET /v3/avatars/looks, and voice_id comes from GET /v3/voices or the look's default voice.
In HeyGen's v3 API, the avatar_id you send is the id of an avatar look. List looks with GET /v3/avatars/looks and copy a look's id into POST /v3/videos or POST /v3/video-agents. For the voice, each look carries a default_voice_id, and GET /v3/voices lists the rest by voice_id.
Every HeyGen fact here is quoted from HeyGen's own developer pages, read on 2026-09-29: Avatar Looks, Browse Voices, Error Codes and the Endpoint Version Comparison. The short Sume section at the end comes from Create new avatar.
How do I get a HeyGen avatar ID from the API?
HeyGen calls one outfit, pose or style of a character a look, and says the look is "the value you pass as avatar_id to video creation". The list call is paged: 20 looks by default, up to 50 with limit, and when has_more is true you pass next_token back as token.
ownership=publicreturns HeyGen's presets,ownership=privateyour own avatars; omit it for both.avatar_typefilters tostudio_avatar,digital_twinorphoto_avatar.group_idreturns every look of one character.- Check
supported_api_enginesbefore you request anengine: an engine the look doesn't list returnsinvalid_parameter. Omittingengineuses Avatar IV. - For private avatars,
statusshows training:processing,completedorfailed.
curl "https://api.heygen.com/v3/avatars/looks?ownership=private&limit=5" \
-H "X-Api-Key: $HEYGEN_API_KEY"Where do I find a HeyGen voice ID?
Two places. Each look in the list above has a default_voice_id. For any other voice, call GET /v3/voices, filter by language or gender, and use the voice_id it returns in POST /v3/videos, POST /v3/video-agents or POST /v3/voices/speech.
One default trips people up: type defaults to "public", the shared library. Your cloned voices only appear with type=private. You can also leave voice_id out of a v3 avatar video: HeyGen's create reference says the avatar's default voice is used as the fallback when avatar_id is set.
Why does my old avatar ID or endpoint not work?
Older tutorials use v1 and v2 routes such as GET /v1/avatar.list and GET /v2/avatars. HeyGen maps these to GET /v3/avatars, which lists avatar groups (characters), and voice listing to GET /v3/voices. The id a v3 video takes is still a look id from GET /v3/avatars/looks. It says v1/v2 endpoints stay operational until October 31, 2026 and will be retired from November 1, 2026. The HeyGen v2 to v3 migration post covers the switch.
What does avatar_not_found mean?
It's a 404: HeyGen found no avatar with that id. The page asks you to verify the id, that a new avatar has finished training, and that the avatar belongs to your account or is public. The table lists the other id errors worth knowing.
| Error code | HTTP status | What HeyGen says it means |
|---|---|---|
avatar_not_found | 404 | The avatar_id is wrong, the avatar hasn't finished training, or it isn't yours or public |
voice_not_found | 404 | The voice_id is wrong or not in your account; a cloned voice may still be processing |
avatar_not_usable | 400 | The avatar failed content moderation or its creation failed; pick another |
avatar_consent_required | 400 | The avatar group needs its consent flow completed first |
voice_not_usable | 403 | The voice is in a state that blocks generation; retrying won't fix it |
plan_upgrade_required | 402 | For example, a premium avatar that isn't on your plan |
How does Sume name avatars instead?
On Sume the avatar id is a name you pick: you choose an avatar_handle when you create the avatar; a leading @ is allowed and stored without it. A talking-video request then references a ready avatar by that same avatar_handle (Generate avatar video). GET /v1/avatar-1.0/avatars lists your avatars; it is in the Sume API reference.
For the API key setup on HeyGen's side, see how to get a HeyGen API key.
Sources
Related posts
More in Developers
- How does the Higgsfield API work? Requests, limits, billing
Higgsfield's API is asynchronous: submit to a model endpoint, keep the request_id, poll or take a webhook, download. Billing and limits explained.
- httpx retry: what HTTPTransport(retries=n) covers
httpx retries only ConnectError and ConnectTimeout, via HTTPTransport(retries=n). For read errors, 429 and 503, write a loop that keeps one Idempotency-Key.
- Ideogram character reference API: what Sume passes through
Ideogram's API has character reference. Sume lists ideogram/ideogram-v3 with input_references, low, medium, high quality; no character reference is documented.
- Image API provider.only and provider.order: which slug works?
Sume's image API takes provider.only and provider.order but lists one endpoint per model, slug sume. Which routing fields do anything, and the 400 for the rest.
Written by Sume