Skip to main content

Create a Video with the Agent

Let the AI pick the avatar, voice, and layout from a text prompt:
heygen video-agent create "A presenter explaining our product launch in 30 seconds"
Output
{
  "session_id": "sess_abc123",
  "status": "generating",
  "video_id": "vid_xyz789",
  "created_at": 1711288320
}
Browse available styles first:
heygen video-agent styles

Create a Video with Full Control

Skip the agent and specify every detail yourself:
heygen video create \
  --avatar-id avt_angela_01 \
  --voice-id 1bd001e7e50f421d891986aad5e3e5d2 \
  --script "Welcome to our Q4 earnings call." \
  --aspect-ratio 16:9 \
  --wait
With --wait, the CLI polls until completion and returns the full video detail:
Output
{
  "id": "vid_qr8821",
  "status": "completed",
  "video_url": "https://files.heygen.com/video/vid_qr8821.mp4",
  "duration": 12.4,
  "created_at": 1711288320,
  "completed_at": 1711288422
}
With --human --wait:
Output
✓ Video vid_qr8821 created
◐ Waiting for completion...
✓ Done in 1m 42s
  URL  https://files.heygen.com/video/vid_qr8821.mp4

Text to Speech

Generate standalone audio using the voice speech command:
heygen voice speech "Hello world, welcome to HeyGen." \
  --voice-id 1bd001e7e50f421d891986aad5e3e5d2
Output
{
  "audio_url": "https://files.heygen.com/audio/req_abc123.mp3",
  "duration": 2.1,
  "request_id": "req_abc123"
}
Download directly with -o:
heygen voice speech "Hello world, welcome to HeyGen." \
  --voice-id 1bd001e7e50f421d891986aad5e3e5d2 \
  -o hello.mp3

List & Filter Voices

Browse voices available for TTS:
heygen voice list --language English --gender female --limit 3
Output
{
  "data": [
    {
      "voice_id": "1bd001e7e50f421d891986aad5e3e5d2",
      "name": "Jenny",
      "language": "English",
      "gender": "female",
      "type": "public",
      "preview_audio_url": "https://files.heygen.com/voice/jenny_preview.mp3"
    }
  ],
  "has_more": true,
  "next_token": "eyJsYXN0X2lkIjoiMWJkMDAxZTcifQ"
}

Avatar Looks

Browse specific outfits and styles for an avatar:
heygen avatar looks --group-id avt_angela_01 --limit 5
Output
{
  "data": [
    {
      "id": "angela_business_01",
      "name": "Business Suit",
      "avatar_type": "studio_avatar",
      "group_id": "avt_angela_01",
      "gender": "female",
      "tags": ["formal", "business"],
      "default_voice_id": "1bd001e7e50f421d891986aad5e3e5d2",
      "preview_image_url": "https://files.heygen.com/look/angela_business_01.jpg"
    }
  ],
  "has_more": false,
  "next_token": null
}
The id from a look is what you pass as --avatar-id to heygen video create. Get details for a specific look:
heygen avatar looks get angela_business_01

Translate a Video

Dub and lip-sync an existing video:
heygen translate create \
  --video-url "https://example.com/my-video.mp4" \
  --output-language es \
  --wait
Without --wait:
Output
{
  "video_translate_id": "trl_55f"
}
With --wait, the CLI polls until completion and returns the full translation detail. Manage existing translations:
heygen translate list
heygen translate get trl_55f
heygen translate caption trl_55f
heygen translate delete trl_55f --force

Upload an Asset

Upload a file to use as an avatar image, audio source, or background:
heygen asset upload ./my-photo.jpg
Output
{
  "asset_id": "ast_abc123",
  "url": "https://files.heygen.com/asset/ast_abc123.jpg"
}

Webhooks

Register an endpoint to receive event notifications:
heygen webhook create \
  --url "https://example.com/webhook" \
  --events avatar_video.success,avatar_video.fail
Output
{
  "endpoint_id": "ep_abc123",
  "url": "https://example.com/webhook",
  "events": ["avatar_video.success", "avatar_video.fail"],
  "status": "enabled",
  "created_at": "2025-03-24T14:32:00Z",
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxx"
}
Store the secret securely — it’s used to verify webhook signatures and won’t be shown again. Use heygen webhook rotate-secret <endpoint_id> to generate a new one.
List all available event types:
heygen webhook event-types
Update or delete an endpoint:
heygen webhook update ep_abc123 --events avatar_video.success
heygen webhook delete ep_abc123 --force

Scripting & Agent Integration

Since JSON is the default output and all non-data goes to stderr, piping into other tools works without any extra flags.

Create and immediately open in browser

VIDEO_ID=$(heygen video-agent create "Demo video" | jq -r '.video_id')
heygen video get $VIDEO_ID --wait | jq -r '.video_url' | xargs open

Batch translate into multiple languages

for lang in es fr de ja ko; do
  heygen translate create \
    --video-url "https://example.com/source.mp4" \
    --output-language $lang --wait --quiet
  echo "✓ $lang done"
done

Agent workflow: create and parse

RESULT=$(heygen video create \
  --avatar-id avt_angela_01 \
  --voice-id 1bd001e7e50f421d891986aad5e3e5d2 \
  --script "Weekly update for the team." \
  --wait)

STATUS=$(echo "$RESULT" | jq -r '.status')
URL=$(echo "$RESULT" | jq -r '.video_url')

if [ "$STATUS" = "completed" ]; then
  curl -o weekly-update.mp4 "$URL"
fi

Auto-paginate through all avatars

heygen avatar list --all | jq -r '.data[].name'

Pipe a script file into video create

cat script.txt | heygen video create \
  --avatar-id avt_angela_01 \
  --voice-id 1bd001e7e50f421d891986aad5e3e5d2 \
  --script - \
  --wait