Get your API key

Go to Settings → API in the HeyGen dashboard and generate a key. Save it — you can’t view it again.

export HEYGEN_API_KEY="your-api-key-here"

Create a video

Send a prompt to the Video Agent and let it handle the rest:

  • curl
  • Python
  • Node.js

Request

curl -X POST "https://api.heygen.com/v3/video-agents" \
  -H "X-Api-Key: $HEYGEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A presenter explaining our product launch in 30 seconds"}'

Request

import requests

resp = requests.post(
    "https://api.heygen.com/v3/video-agents",
    headers={"X-Api-Key": HEYGEN_API_KEY},
    json={"prompt": "A presenter explaining our product launch in 30 seconds"},
)
data = resp.json()["data"]
print(data["video_id"])

Request

const resp = await fetch("https://api.heygen.com/v3/video-agents", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.HEYGEN_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompt: "A presenter explaining our product launch in 30 seconds",
  }),
});
const { data } = await resp.json();
console.log(data.video_id);

Response

{
  "data": {
    "session_id": "sess_abc123",
    "status": "generating",
    "video_id": "vid_xyz789",
    "created_at": 1711382400
  }
}

Poll for the result

Video generation is async. Use the video_id to check status:

  • curl
  • Python
  • Node.js

Request

curl -X GET "https://api.heygen.com/v3/videos/vid_xyz789" \
  -H "X-Api-Key: $HEYGEN_API_KEY"

Request

import time

video_id = "vid_xyz789"
while True:
    resp = requests.get(
        f"https://api.heygen.com/v3/videos/{{video_id}}",
        headers={"X-Api-Key": HEYGEN_API_KEY},
    )
    video = resp.json()["data"]
    if video["status"] in ("completed", "failed"):
        break
    time.sleep(10)

print(video["video_url"])

Request

const poll = async (videoId) => {
  while (true) {
    const resp = await fetch(
      `https://api.heygen.com/v3/videos/${videoId}`,
      { headers: { "X-Api-Key": process.env.HEYGEN_API_KEY } }
    );
    const { data } = await resp.json();
    if (data.status === "completed" || data.status === "failed") return data;
    await new Promise((r) => setTimeout(r, 10000));
  }
};
const video = await poll("vid_xyz789");
console.log(video.video_url);

Response (completed)

{
  "data": {
    "id": "vid_xyz789",
    "status": "completed",
    "video_url": "https://files.heygen.com/video/vid_xyz789.mp4",
    "thumbnail_url": "https://files.heygen.com/thumb/vid_xyz789.jpg",
    "duration": 32.5
  }
}

Status moves through pending → processing → completed | failed. Once completed, download from video_url.

Skip polling by passing a callback_url in your creation request to get a webhook notification instead.

Resources

Video Agent
Generate videos from a text prompt — the agent handles avatar, script, and production.
Video Translation
Translate videos into 30+ languages with natural voice cloning and lip-sync.
Webhooks
Get notified when videos, translations, and avatars finish processing.
API Limits and Costs
Rate limits, usage, and pricing per operation.

Tools

CLI
Script video creation and translation from your terminal.
MCP Server
Connect HeyGen to AI agents and copilots via Model Context Protocol.
Authentication
API key setup, OAuth tokens, and request signing.

Choosing the Right Video API