---
title: "Create Video Generation"
method: POST
path: "/v3/video-generations"
tags: ["Video Generations"]
---

# Create Video Generation

`POST /v3/video-generations`

## Request

- Base URL: `https://api.heygen.com`
- URL: `https://api.heygen.com/v3/video-generations`
- Auth: one of:
  - API key in header `x-api-key`
  - HTTP bearer

Generate a video from a prompt with the model `model` names, each with its own options: `seedance-2.5`, optionally guided by reference images and reference videos, or `minimax-h3-max`, optionally opening on a `first_frame` image, ending on an `end_frame`, steered through a `middle_frame`, and guided by reference images, reference videos and reference audio. The request answers 200 once the generation is accepted, with `status` `pending`, and the generation finishes whether or not it is read. Read it with `GET /v3/video-generations/{generation_id}` until it is `completed` with a time-limited `video_url`, or `failed`, or pass `callback_url` to receive `video_generation.success` or `video_generation.fail` when it finishes; the workspace's configured webhook endpoints receive the same events. Send an `Idempotency-Key` header with every request: it is required. Repeating a request with the same key and body returns the original generation instead of submitting again. The workspace's API credits are charged at the model's list price when the request starts: the price follows the output length and resolution (and for `seedance-2.5` the aspect ratio), plus the length of any reference videos (and for `minimax-h3-max` their frame rate, the shape of each reference image, the length of any reference audio and any first, end or middle frame). A request the credits cannot cover is refused with 402 `insufficient_credit` before any work starts, and a generation that fails is refunded. The request body is capped at about 22 MiB, so inline `base64` references together must stay under about 16 MiB decoded; send larger or additional references as `url` or `asset_id`.

## Headers

- `Idempotency-Key` string, required

## Request body

- union
  - SeedanceVideoGenerationCreateRequest
    - `model` 'seedance-2.5', required: Video model. Each model accepts its own options.
    - `prompt` string, required: What the video should show.
    - `duration` integer: Output length in whole seconds, 4 to 30.
    - `resolution` '480p' | '720p' | '1080p': Output resolution.
    - `aspect_ratio` '16:9' | '1:1' | '9:16': Output aspect ratio.
    - `generate_audio` boolean: Generate a soundtrack with the video. It does not change the price.
    - `reference_images` union[]: Reference images, at most 30.
      - union
        - AssetUrl: Asset input via publicly accessible HTTPS URL.
          - `type` 'url', required: Input type discriminator
          - `url` string, required: Publicly accessible HTTPS URL for the asset
        - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
          - `type` 'asset_id', required: Input type discriminator
          - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
        - AssetBase64: Asset input via base64-encoded content.
          - `type` 'base64', required: Input type discriminator
          - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
          - `data` string, required: Base64-encoded file content
    - `reference_videos` union[]: Reference videos, at most 10, each 2 to 10 seconds and 30 seconds in total. Their length adds to the price.
      - union
        - AssetUrl: Asset input via publicly accessible HTTPS URL.
          - `type` 'url', required: Input type discriminator
          - `url` string, required: Publicly accessible HTTPS URL for the asset
        - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
          - `type` 'asset_id', required: Input type discriminator
          - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
        - AssetBase64: Asset input via base64-encoded content.
          - `type` 'base64', required: Input type discriminator
          - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
          - `data` string, required: Base64-encoded file content
    - `callback_url` string, nullable: Webhook URL to receive a POST notification (`video_generation.success` or `video_generation.fail`) when the generation finishes, in addition to the workspace's configured webhook endpoints.
    - `callback_id` string, nullable: Caller-defined identifier echoed back in the webhook payload.
  - MinimaxH3MaxVideoGenerationCreateRequest
    - `model` 'minimax-h3-max', required: Video model. Each model accepts its own options.
    - `prompt` string, required: What the video should show, at most 50,000 characters. Refer to the references by kind and order: Image 1, Image 2, Video 1, Audio 1 and so on.
    - `duration` number: Output length in seconds, 0.92 to 15; fractions of a second are allowed. The price is per second of this length.
    - `resolution` '480p' | '768p' | '1080p': Output resolution. 1080p is refined from a 768p render.
    - `aspect_ratio` 'adaptive' | '21:9' | '16:9' | '4:3' | '1:1' | '3:4' | '9:16': Output aspect ratio. With a `first_frame` the video takes the first frame's shape whatever this says; `adaptive` otherwise follows the reference videos.
    - `prompt_expansion_mode` 'disabled' | 'balanced' | 'quality': How much the prompt is rewritten before generation: `disabled` sends it as written, `balanced` takes about a second, `quality` up to about 30 seconds for a richer prompt. It does not change the price.
    - `seed` integer, nullable: Generation seed. A random seed is chosen when omitted.
    - `first_frame` union: An image the video opens on exactly. It adds one step of tokens to the references' total.
      - AssetUrl: Asset input via publicly accessible HTTPS URL.
        - `type` 'url', required: Input type discriminator
        - `url` string, required: Publicly accessible HTTPS URL for the asset
      - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
        - `type` 'asset_id', required: Input type discriminator
        - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
      - AssetBase64: Asset input via base64-encoded content.
        - `type` 'base64', required: Input type discriminator
        - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
        - `data` string, required: Base64-encoded file content
    - `end_frame` union: An image the video ends on exactly. It adds one step of tokens to the references' total.
      - AssetUrl: Asset input via publicly accessible HTTPS URL.
        - `type` 'url', required: Input type discriminator
        - `url` string, required: Publicly accessible HTTPS URL for the asset
      - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
        - `type` 'asset_id', required: Input type discriminator
        - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
      - AssetBase64: Asset input via base64-encoded content.
        - `type` 'base64', required: Input type discriminator
        - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
        - `data` string, required: Base64-encoded file content
    - `middle_frame` union: An image that guides the video at `middle_frame_time`. It needs `first_frame`, `end_frame` and a 480p or 768p `resolution`, and adds one step of tokens to the references' total.
      - AssetUrl: Asset input via publicly accessible HTTPS URL.
        - `type` 'url', required: Input type discriminator
        - `url` string, required: Publicly accessible HTTPS URL for the asset
      - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
        - `type` 'asset_id', required: Input type discriminator
        - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
      - AssetBase64: Asset input via base64-encoded content.
        - `type` 'base64', required: Input type discriminator
        - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
        - `data` string, required: Base64-encoded file content
    - `middle_frame_time` number, nullable: Seconds from the start at which `middle_frame` guides the video, required with it. It is rounded to the nearest frame at 24 fps and must fall strictly between the first and last frames of `duration`.
    - `reference_images` union[]: Reference images for people, objects and style, at most 9, each between 2:5 and 5:2. Each adds tokens by its aspect ratio (1,024 for a square image) to the references' total.
      - union
        - AssetUrl: Asset input via publicly accessible HTTPS URL.
          - `type` 'url', required: Input type discriminator
          - `url` string, required: Publicly accessible HTTPS URL for the asset
        - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
          - `type` 'asset_id', required: Input type discriminator
          - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
        - AssetBase64: Asset input via base64-encoded content.
          - `type` 'base64', required: Input type discriminator
          - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
          - `data` string, required: Base64-encoded file content
    - `reference_videos` union[]: Reference videos for motion, people and style, at most 3, each 2 to 15 seconds and 15 seconds in total. Each adds tokens for its frames to the references' total: up to 30 a second of its length, and at most 30 a second of the output duration, but never less than a 24 fps clip as long as the shorter of the two.
      - union
        - AssetUrl: Asset input via publicly accessible HTTPS URL.
          - `type` 'url', required: Input type discriminator
          - `url` string, required: Publicly accessible HTTPS URL for the asset
        - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
          - `type` 'asset_id', required: Input type discriminator
          - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
        - AssetBase64: Asset input via base64-encoded content.
          - `type` 'base64', required: Input type discriminator
          - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
          - `data` string, required: Base64-encoded file content
    - `reference_audio` union[]: Reference audio clips, at most 3, each 2 to 15 seconds and 15 seconds in total. Each adds about 80 tokens a second to the references' total. Reference images, videos and audio clips together are at least 1 and at most 12 files, and their tokens past the first 4,096 add to the price.
      - union
        - AssetUrl: Asset input via publicly accessible HTTPS URL.
          - `type` 'url', required: Input type discriminator
          - `url` string, required: Publicly accessible HTTPS URL for the asset
        - AssetId: Asset input via HeyGen asset ID from the asset upload endpoint.
          - `type` 'asset_id', required: Input type discriminator
          - `asset_id` string, required: HeyGen asset ID from the asset upload endpoint
        - AssetBase64: Asset input via base64-encoded content.
          - `type` 'base64', required: Input type discriminator
          - `media_type` string, required: MIME type of the encoded content (e.g. "image/png")
          - `data` string, required: Base64-encoded file content
    - `callback_url` string, nullable: Webhook URL to receive a POST notification (`video_generation.success` or `video_generation.fail`) when the generation finishes, in addition to the workspace's configured webhook endpoints.
    - `callback_id` string, nullable: Caller-defined identifier echoed back in the webhook payload.

## Response `200`

The submitted generation, `pending` until the model finishes.

- object
  - `data` VideoGenerationResponse
    - `id` string, required: The generation id; read it again with GET /v3/video-generations/{id}.
    - `status` 'pending' | 'completed' | 'failed', required
    - `model` 'seedance-2.5' | 'minimax-h3-max', required: The video model that generates the video.
    - `created_at` integer, nullable: Unix seconds.
    - `duration` number, required: The output length the request asked for, in seconds.
    - `resolution` '480p' | '720p' | '768p' | '1080p', required: The output resolution the request asked for.
    - `aspect_ratio` 'adaptive' | '21:9' | '16:9' | '4:3' | '1:1' | '3:4' | '9:16', required: The output aspect ratio the request asked for.
    - `video_url` string, nullable: Time-limited download URL of the mp4; present once completed. Read the generation again for a fresh URL.
    - `duration_seconds` number, nullable: The length of the generated video; present once completed.
    - `failure_code` 'invalid_input' | 'content_policy_violation' | 'vendor_unavailable' | 'vendor_timeout' | 'ai_vendor_access_restricted' | 'insufficient_credit' | 'hf_usage_exhausted' | 'hf_subscription_required' | 'api_key_required' | 'internal_error'
    - `failure_message` string, nullable: A customer-safe explanation; present once failed.

## Other responses

- `400`: Invalid request parameters
- `401`: Authentication failed
- `402`: Insufficient credit
- `403`: Forbidden — `error.code` is one of: `resource_access_denied`, `ai_vendor_access_restricted`.
- `409`: Conflict — `error.code` is one of: `request_in_progress`, `conflict`.
- `429`: Rate limit exceeded

## Changes

- **2026-11-03** `7dfa5e59b4f5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/heygen/apis/heygen-external-api/changes/v3/video-generations/post.md)

---

[API](https://skmtc.dev/heygen/apis/heygen-external-api.md) - [All operations](https://skmtc.dev/heygen/apis/heygen-external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/heygen/apis/heygen-external-api/revisions/7dfa5e59b4f5?raw)
