About ai-video-gen
ai-video-gen is a skill for generating videos from text prompts through the HeyGen API. It is for users creating text-to-video or image-to-video content, with options for providers, aspect ratios, and image guidance.
Key features
- 01Generate video from text prompts
- 02Choose from multiple providers
- 03Configure aspect ratios
- 04Use reference and tail images
- 05Poll jobs and retrieve video URLs
Use cases
- 01Create a video from a written description
- 02Animate a product photo
- 03Make vertical videos for social media
Install
Copy the command and run it in a terminal.
$
npx skills add https:/ / github.com/ heygen-com/ skills --skill ai-video-genAfter installing, type/ai-video-genin Claude Code to confirm it loaded.
Details
From the project READMEVideo Generation (HeyGen API)
Generate AI videos from text prompts. Supports multiple providers (VEO 3.1, Kling, Sora, Runway, Seedance), configurable aspect ratios, and optional reference images for image-to-video generation.
Authentication
All requests require the X-Api-Key header. Set the HEYGEN_API_KEY environment variable.
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
-H "X-Api-Key: $HEYGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"workflow_type": "GenerateVideoNode", "input": {"prompt": "A drone shot flying over a coastal city at sunset"}}'
Default Workflow
- Call
POST /v1/workflows/executionswithworkflow_type: "GenerateVideoNode"and your prompt - Receive a
execution_idin the response - Poll
GET /v1/workflows/executions/{id}every 10 seconds until status iscompleted - Use the returned
video_urlfrom the output
Execute Video Generation
Endpoint
POST https://api.heygen.com/v1/workflows/executions
Request Fields
| Field | Type | Req | Description |
|---|---|---|---|
workflow_type | string | Y | Must be "GenerateVideoNode" |
input.prompt | string | Y | Text description of the video to generate |
input.provider | string | Video generation provider (default: "veo_3_1"). See Providers below. | |
input.aspect_ratio | string | Aspect ratio (default: "16:9"). Common values: "16:9", "9:16", "1:1" | |
input.reference_image_url | string | Reference image URL for image-to-video generation | |
input.tail_image_url | string | Tail image URL for last-frame guidance | |
input.config | object | Provider-specific configuration overrides |
Providers
| Provider | Value | Description |
|---|---|---|
| VEO 3.1 | "veo_3_1" | Google VEO 3.1 (default, highest quality) |
| VEO 3.1 Fast | "veo_3_1_fast" | Faster VEO 3.1 variant |
| VEO 3 | "veo3" | Google VEO 3 |
| VEO 3 Fast | "veo3_fast" | Faster VEO 3 variant |
| VEO 2 | "veo2" | Google VEO 2 |
| Kling Pro | "kling_pro" | Kling Pro model |
| Kling V2 | "kling_v2" | Kling V2 model |
| Sora V2 | "sora_v2" | OpenAI Sora V2 |
| Sora V2 Pro | "sora_v2_pro" | OpenAI Sora V2 Pro |
| Runway Gen-4 | "runway_gen4" | Runway Gen-4 |
| Seedance Lite | "seedance_lite" | Seedance Lite |
| Seedance Pro | "seedance_pro" | Seedance Pro |
| LTX Distilled | "ltx_distilled" | LTX Distilled (fastest) |
curl
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
-H "X-Api-Key: $HEYGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": "A drone shot flying over a coastal city at golden hour, cinematic lighting",
"provider": "veo_3_1",
"aspect_ratio": "16:9"
}
}'
TypeScript
interface GenerateVideoInput {
prompt: string;
provider?: string;
aspect_ratio?: string;
reference_image_url?: string;
tail_image_url?: string;
config?: Record<string, any>;
}
interface ExecuteResponse {
data: {
execution_id: string;
status: "submitted";
};
}
async function generateVideo(input: GenerateVideoInput): Promise<string> {
const response = await fetch("https://api.heygen.com/v1/workflows/executions", {
method: "POST",
headers: {
"X-Api-Key": process.env.HEYGEN_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
workflow_type: "GenerateVideoNode",
input,
}),
});
const json: ExecuteResponse = await response.json();
return json.data.execution_id;
}
Python
import requests
import os
def generate_video(
prompt: str,
provider: str = "veo_3_1",
aspect_ratio: str = "16:9",
reference_image_url: str | None = None,
tail_image_url: str | None = None,
) -> str:
payload = {
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": prompt,
"provider": provider,
"aspect_ratio": aspect_ratio,
},
}
if reference_image_url:
payload["input"]["reference_image_url"] = reference_image_url
if tail_image_url:
payload["input"]["tail_image_url"] = tail_image_url
response = requests.post(
"https://api.heygen.com/v1/workflows/executions",
headers={
"X-Api-Key": os.environ["HEYGEN_API_KEY"],
"Content-Type": "application/json",
},
json=payload,
)
data = response.json()
return data["data"]["execution_id"]
Response Format
{
"data": {
"execution_id": "node-gw-v1d2e3o4",
"status": "submitted"
}
}
Check Status
Endpoint
GET https://api.heygen.com/v1/workflows/executions/{execution_id}
curl
curl -X GET "https://api.heygen.com/v1/workflows/executions/node-gw-v1d2e3o4" \
-H "X-Api-Key: $HEYGEN_API_KEY"
Response Format (Completed)
{
"data": {
"execution_id": "node-gw-v1d2e3o4",
"status": "completed",
"output": {
"video": {
"video_url": "https://resource.heygen.ai/generated/video.mp4",
"video_id": "abc123"
},
"asset_id": "asset-xyz789"
}
}
}
Polling for Completion
async function generateVideoAndWait(
input: GenerateVideoInput,
maxWaitMs = 600000,
pollIntervalMs = 10000
): Promise<{ video_url: string; video_id: string; asset_id: string }> {
const executionId = await generateVideo(input);
console.log(`Submitted video generation: ${executionId}`);
const startTime = Date.now();
while (Date.now() - startTime < maxWaitMs) {
const response = await fetch(
`https://api.heygen.com/v1/workflows/executions/${executionId}`,
{ headers: { "X-Api-Key": process.env.HEYGEN_API_KEY! } }
);
const { data } = await response.json();
switch (data.status) {
case "completed":
return {
video_url: data.output.video.video_url,
video_id: data.output.video.video_id,
asset_id: data.output.asset_id,
};
case "failed":
throw new Error(data.error?.message || "Video generation failed");
case "not_found":
throw new Error("Workflow not found");
default:
await new Promise((r) => setTimeout(r, pollIntervalMs));
}
}
throw new Error("Video generation timed out");
}
Usage Examples
Simple Text-to-Video
curl -X POST "https://api.heygen.com/v1/workflows/executions" \
-H "X-Api-Key: $HEYGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": "A person walking through a sunlit park, shallow depth of field"
}
}'
Image-to-Video
{
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": "Animate this product photo with a slow zoom and soft particle effects",
"reference_image_url": "https://example.com/product-photo.png",
"provider": "kling_pro"
}
}
Vertical Format for Social Media
{
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": "A trendy coffee shop interior, camera slowly panning across the counter",
"aspect_ratio": "9:16",
"provider": "veo_3_1"
}
}
Fast Generation with LTX
{
"workflow_type": "GenerateVideoNode",
"input": {
"prompt": "Abstract colorful shapes morphing and flowing",
"provider": "ltx_distilled"
}
}
Best Practices
- Be descriptive in prompts — include camera movement, lighting, style, and mood details
- Default to VEO 3.1 for highest quality; use
ltx_distilledorveo3_fastwhen speed matters - Use reference images for image-to-video generation — great for animating product photos or still images
- Video generation is the slowest workflow — allow up to 5 minutes, poll every 10 seconds
- Aspect ratio matters — use
9:16for social media stories/reels,16:9for landscape,1:1for square - Output includes
asset_id— use this to reference the generated video in other HeyGen workflows - Output URLs are temporary — download or save generated videos promptly
Comments
Markdown supported