heygen-avatar
Create a persistent HeyGen avatar — a reusable face + voice identity for the agent, the user, or any named character — powered by HeyGen Avatar V technology. Prompt-based creation by default (description → HeyGen builds it); photo upload is optional for real-person digital twins. Use when: (1) giving the agent a face + voice so it can present videos ("bring yourself to life", "create your avatar", "give yourself an avatar", "design a presenter", "set up an avatar", "let's make an avatar"), (2) the user wants to appear in videos as themselves ("create my avatar", "I want my face in a video", "digital twin of me", "build me an avatar"), (3) building a named character presenter ("create an avatar called Cleo", "design a character named X"), (4) establishing HeyGen identity before making videos — the correct FIRST step when no avatar exists yet. Chain signal: when the user says both an identity/avatar action AND a video action in the same request ("create an avatar AND make a video", "set up identity THEN create a video", "design a presenter AND immediately record"), run heygen-avatar first, then heygen-video. Returns avatar_id + voice_id — pass directly to heygen-video to create HeyGen videos. NOT for: generating videos (use heygen-video), translating videos, or TTS-only tasks.
NPX Install
npx skill4agent add heygen-com/skills heygen-avatarTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →HeyGen Avatar Designer
AVATAR-<NAME>.mdFiles & Paths
| Operation | Path | Purpose |
|---|---|---|
| Read | | Extract identity details when creating an avatar for the agent |
| Read | | Load existing avatar identity (for variant looks, voice updates) |
| Write | | Save new avatar identity after creation |
| Write | | Role aliases, see Phase 5 |
| Temp write | | Voice preview audio (downloaded for user playback, deleted after session) |
| Remote upload | HeyGen (via | User-provided photos uploaded to HeyGen for digital-twin creation |
Language Awareness
user_languageenjaeskozhfrdept- Communicate with the user in their language. All questions, status updates, confirmations, and error messages should be in .
user_language - Voice design prompts and selection respect . When designing or selecting a voice, specify the target language so the voice library returns matches that speak it.
user_language - Technical directives stay in English — enum values (,
Young Adult,Realistic, etc.) are API-level and not translated.landscape
UX Rules
- Be concise. No avatar IDs, group IDs, or raw API payloads in chat. Report the result (avatar created, ready to use) not the plumbing.
- No internal jargon. Never mention internal phase names ("Phase 0", "Phase 5 Symlink Maintenance") to the user. The user sees natural conversation: "Setting up your avatar\u2026" not "Running Phase 2 avatar creation."
- One or two questions per phase. Don't batch-ask. Walk phases in order, ask the smallest set of questions needed to proceed.
- Read workspace files before asking. ,
SOUL.md,IDENTITY.mdat the workspace root contain identity. Check them first. Only ask the user for what's genuinely missing.AVATAR-*.md - Don't narrate skill internals. Never say "let me read the workflow," "checking the reference files," "loading the avatar discovery guide." Read silently. The user sees questions and results, not internal navigation.
- Don't announce what you're about to do. Skip meta-commentary like "Creating the avatar now." Just do the work. If a step takes time, the next thing the user hears should be the result (or a checkpoint question).
- Never narrate transport choice. MCP vs CLI is internal. Pick the transport silently and never mention it. If both are unavailable, ask the user to configure one without explaining why.
Start Here (Critical)
Before You Start (environment detection)
SOUL.md- Found → OpenClaw environment. Skip this entire section and go straight to Phase 0. Workspace-native identity (SOUL.md, IDENTITY.md) will drive agent onboarding.
- Not found → Claude Code environment, no workspace identity files. Still go to Phase 0 next — do NOT skip ahead to listing user avatars or asking the user for a photo.
API Mode Detection
mcp__heygen__*heygenheygen --versionHEYGEN_API_KEYheygen auth login~/.heygen/credentials--versioncurl -fsSL https://static.heygen.ai/cli/install.sh | bashheygen auth login- Index: — full sitemap
GET https://developers.heygen.com/llms.txt - Any page: Append to the URL for clean markdown
.md - Or run
heygen <noun> <verb> --help - Read the spec, THEN build your request. Never guess field names.
Avatar File Convention
AVATAR-<NAME>.mdAVATAR-EVE.md ← agent (named, canonical)
AVATAR-KEN.md ← user (named, canonical)
AVATAR-CLEO.md ← character (named, canonical)AVATAR-AGENT.md → AVATAR-<CURRENT-AGENT-NAME>.md (symlink)
AVATAR-USER.md → AVATAR-<CURRENT-USER-NAME>.md (symlink)# Avatar: <Name>
## Appearance
- Age: <natural language>
- Gender: <natural language>
- Ethnicity: <natural language>
- Hair: <natural language>
- Build: <natural language>
- Features: <natural language>
- Style: <natural language>
- Reference: <optional workspace-relative path or URL>
## Voice
- Tone: <natural language>
- Accent: <natural language>
- Energy: <natural language>
- Think: <one-line analogy>
## HeyGen
- Group ID: <character identity anchor — THE stable reference, never changes>
- Voice ID: <matched or designed voice>
- Voice Name: <human-readable>
- Voice Designed: <true if custom-designed, false if picked from catalog>
- Voice Seed: <seed value used, if designed>
- Looks: landscape=<look_id>, portrait=<look_id>, square=<look_id>
- Last Synced: <ISO timestamp>
⚠️ look_ids are ephemeral — always resolve fresh from group_id at runtime via `heygen avatar looks list --group-id <id>` (or MCP `list_avatar_looks`). Never hardcode look_id as the primary avatar reference.Skill Announcement
🎭 Using: heygen-avatar — creating an avatar for [name]
Workflow
Phase 0 — Who Are We Creating?
- User (explicit only) — "create my avatar", "make me an avatar", "I want my face in a video", "a digital twin of me", "based on my photo". Requires a possessive pronoun referring to the user OR explicit mention of their photo. Ask for their name if not obvious.
- Named character (explicit only) — "create an avatar called Cleo", "design a character named X", "build a presenter named Y" → use the given name.
- Agent (default) — everything else: "create your avatar", "bring yourself to life", "set up an avatar", "let's make an avatar", "create an avatar", "design a presenter", "I want you to appear in videos", or any ambiguous phrasing. Read for name.
IDENTITY.md
AVATAR-<NAME>.md- AVATAR file exists + HeyGen section filled in → "You already have an avatar set up. Want to add a new look, update it, or start fresh?" Wait for answer.
- AVATAR file exists but HeyGen section empty → skip to Phase 2.
- No AVATAR file → proceed to Phase 1.
- For agent target: read (follow symlink) and compare to
AVATAR-AGENT.md. If they differ (e.g.,AVATAR-<CURRENT-AGENT-NAME>.md→AVATAR-AGENT.mdbecause the agent identity changed since the last run), re-link in Phase 5 even if no other changes are made. The named file is canonical, but the alias must match the current identity, not the historical one.AVATAR-OLD-NAME.md - For user target: same check on .
AVATAR-USER.md - For named character: no alias to check.
AVATAR-<USER>.mdlist_avatar_groups(ownership=private)heygen avatar list --ownership privatePhase 1 — Identity Extraction
- Read ,
SOUL.md, and any existingIDENTITY.mdfrom the workspace root.AVATAR-<NAME>.md - If SOUL.md or IDENTITY.md is found → extract appearance and voice traits silently. Do NOT ask the user "describe your appearance" — the agent IS the subject, and its identity lives in those files. If the files describe only personality / values with no physical description, do NOT hallucinate traits. Ask the user conversationally for the missing appearance traits only (one or two at a time).
- If neither file is found (e.g., Claude Code environment with no workspace identity) → ask the user to describe the agent's appearance and voice conversationally.
- Proceed directly to Type A (prompt) creation in Phase 2 by default. Do NOT ask for a photo unless the user volunteers one or explicitly asks for photo realism — agents almost always use prompt-based creation.
- Conversational onboarding. Ask naturally about appearance and voice — one or two questions at a time, not a form. Communicate in .
user_language - User path only: after the onboarding Q&A, run the Reference Photo Nudge below.
- Named character path: skip the nudge, go straight to Type A (prompt) creation.
AVATAR-<NAME>.mdReference Photo Nudge (user path only)
- Check AVATAR file's Appearance → Reference field first. If a photo is already on file, skip asking and use it.
- Otherwise, ask one sentence: "Got a headshot? It gives better face consistency for videos of you. I can also generate from your description — just say 'skip.'"
- Photo provided → upload via MCP or
upload_asset, then Type B (photo) creation in Phase 2.heygen asset create --file <path> - Skip → Type A (prompt) creation in Phase 2.
Phase 2 — Avatar Creation
avatar_group_idavatar_group_idcreate_prompt_avatar(name=<name>, prompt=<appearance>, avatar_group_id=<optional>)heygen avatar create -d '{"type":"prompt","name":"...","prompt":"...","avatar_group_id":"..."}'-create_photo_avatar(name=<name>, file=<file_object>, avatar_group_id=<optional>)heygen avatar create -d '{"type":"photo","name":"...","file":{"type":"url","url":"..."},"avatar_group_id":"..."}'- — public image URL
{ "type": "url", "url": "https://..." } - — from
{ "type": "asset_id", "asset_id": "<id>" }heygen asset create --file <path> - — inline
{ "type": "base64", "media_type": "image/png", "data": "<base64>" }
avatar_item.idavatar_item.group_id- age: Young Adult | Early Middle Age | Late Middle Age | Senior | Unspecified
- gender: Man | Woman | Unspecified
- ethnicity: White | Black | Asian American | East Asian | South East Asian | South Asian | Middle Eastern | Pacific | Hispanic | Unspecified
- style: Realistic | Pixar | Cinematic | Vintage | Noir | Cyberpunk | Unspecified
- orientation: square | horizontal | vertical
- pose: half_body | close_up | full_body
Appearance: "[prompt]" Settings: Young Adult | Woman | East Asian | Realistic Look good? (yes / adjust / completely different)
Phase 3 — Voice
user_languagePath A — Voice Design (preferred)
user_language"A calm, warm female voice. Professional but approachable. Japanese speaker."design_voice(prompt=<voice description>, seed=0)heygen voice create --prompt "..." --seed 0--gender--locale- Download each to a temp path (any standard download method works — no HeyGen auth needed, these are public S3 URLs)
preview_audio_url - Send as audio attachment: so it plays inline in Telegram/Discord
message(action:send, media:"<path>", caption:"Option <n>: <voice_name> — <gender>, <language>") - After all previews sent, present selection buttons
"None of these hitting right? I can try a different set (same description, different variations) or you can tweak the description."
seed- Clean up /tmp files after user picks
Path B — Voice Browse (fallback)
list_voices(type=private)list_voices(type=public, language=<lang>, gender=<gender>)heygen voice list --type privateheygen voice list --type public --language <lang> --gender <gender>- Read the Voice section from the AVATAR file
- Filter by gender and language
- Pick top 3 candidates based on personality match
- Present with inline audio previews (same download + send pattern as Path A)
- ⛔ STOP. Wait for the user to pick. Do NOT auto-select.
Phase 4 — Save to AVATAR File
AVATAR-<NAME>.md## HeyGen
- Group ID: <avatar_item.group_id — THE stable reference, never changes>
- Voice ID: <chosen voice_id>
- Voice Name: <voice name>
- Voice Designed: <true if custom-designed, false if picked from catalog>
- Voice Seed: <seed value used, if designed>
- Looks: <orientation>=<avatar_item.id> (e.g., landscape=<look_id>, portrait=<look_id>)
- Last Synced: <ISO timestamp>
⚠️ look_ids are ephemeral — always resolve fresh from group_id at runtime via `heygen avatar looks list --group-id <id>` (or MCP `list_avatar_looks`). Never hardcode look_id as the primary avatar reference.user_languagePhase 5 — Maintain Role Alias
AVATAR-<NAME>.md- Agent target → symlink →
AVATAR-AGENT.mdAVATAR-<NAME>.md - User target → symlink →
AVATAR-USER.mdAVATAR-<NAME>.md - Named character → no role alias. Named characters are referenced by
name only (e.g., ); they are not the agent or the user.
AVATAR-CLEO.md
cdln -s|| echo# Agent
cd "$WORKSPACE_ROOT" && ln -sf AVATAR-<NAME>.md AVATAR-AGENT.md \
|| echo "role alias skipped: fs doesn't support symlinks"
# User
cd "$WORKSPACE_ROOT" && ln -sf AVATAR-<NAME>.md AVATAR-USER.md \
|| echo "role alias skipped: fs doesn't support symlinks"ln -sfIDENTITY.mdAVATAR-AGENT.mdAVATAR-AGENT.mdPhase 6 — Test (Optional)
create_video_agent(avatar_id=<avatar_id>, voice_id=<voice_id>, prompt=<greeting>)heygen video-agent create --avatar-id <id> --voice-id <id> --prompt "..." --waituser_languageIteration Flow
- "Adjust the prompt" → Mode 2 with existing group_id (keeps the character, adds a new look). Only Mode 1 if they say "start completely over."
- "Add a new look" / "different outfit" → Mode 2 with existing group_id. Add to Looks in AVATAR file.
- "Try a different voice" → back to Phase 3
- "Start completely over" → Mode 1, new character. Overwrite HeyGen section.
UX Rules
Video Producer Integration
heygen-video- Named request ("Make a video with Eve") → read .
AVATAR-EVE.md - Agent self-reference ("make a video of yourself", "give us a video
update") → read (symlink to current agent's named file).
AVATAR-AGENT.md - User self-reference ("make a video of me", "my video update") → read
(symlink to current user's named file).
AVATAR-USER.md - No AVATAR file or symlink → fall back to stock avatars or ask user.
cat AVATAR-AGENT.mdError Handling
- Missing SOUL.md/IDENTITY.md → conversational onboarding, write AVATAR file from answers
- API fails → retry once, then ask user to check API key
- Voice match poor → show all available voices, let user browse
- Asset upload fails → skip reference image, try prompt-only creation
- Existing avatar file with stale HeyGen IDs → offer to regenerate or keep