> ## Documentation Index
> Fetch the complete documentation index at: https://heygen-1fa696a7.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate Video from Template

> Generates a video from the template by replacing its variables (text, image, video, audio, character, voice). Use scene_ids to select, reorder, or repeat scenes — scenes must already exist in the template; the API cannot create new ones. Returns the created video object; poll GET /v3/videos/{video_id} or use webhooks for completion. Idempotent replays return the original creation-time snapshot (status and URLs as of the first request), not the video's current state.



## OpenAPI

````yaml /openapi/external-api.json post /v3/templates/{template_id}
openapi: 3.1.0
info:
  title: HeyGen External API
  version: 1.0.0
  description: >-
    HeyGen's external API for programmatic AI video creation. See
    https://docs.heygen.com for full documentation.
  contact:
    name: HeyGen Product Infra
    url: https://heygen.com
servers:
  - url: https://api.heygen.com
    description: Production
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Video Agent
    description: Create videos from text prompts using AI
  - name: Videos
    description: Create, list, retrieve, and delete videos
  - name: Templates
    description: Generate videos from reusable templates by replacing their variables
  - name: Voices
    description: Text-to-speech and voice management
  - name: Audio
    description: Search the background-music and sound-effects catalog
  - name: Video Translate
    description: Translate videos into other languages
  - name: AI Clipping
    description: Turn long-form videos into ready-to-share short clips with captions
  - name: Batches
    description: Create and track batches of videos.
  - name: Video Translation Batches
    description: Create and track batches of video translations.
  - name: Lipsync Batches
    description: Create and track batches of lipsyncs.
  - name: Asset Batches
    description: Create and track batches of direct-to-S3 asset uploads.
  - name: User
    description: Account information and billing
  - name: Avatars
    description: List and manage avatars and looks
  - name: Avatar Realtime
    description: >-
      Low-latency streaming avatar sessions — create a stream, poll for its HLS
      URL, push text, consume per-word timestamps
  - name: Assets
    description: Upload files for use in video creation
  - name: Webhooks
    description: Manage webhook endpoints and events
  - name: Lipsync
    description: Dub or replace audio on existing videos
  - name: Brand
    description: >-
      Brand-related resources — brand kits (colors, fonts, logos) and brand
      glossaries (custom term translations)
  - name: HyperFrames
    description: Render HyperFrames composition zips into video — separate from /v3/videos
paths:
  /v3/templates/{template_id}:
    post:
      tags:
        - Templates
      summary: Generate Video from Template
      description: >-
        Generates a video from the template by replacing its variables (text,
        image, video, audio, character, voice). Use scene_ids to select,
        reorder, or repeat scenes — scenes must already exist in the template;
        the API cannot create new ones. Returns the created video object; poll
        GET /v3/videos/{video_id} or use webhooks for completion. Idempotent
        replays return the original creation-time snapshot (status and URLs as
        of the first request), not the video's current state.
      operationId: generateFromTemplateV3
      parameters:
        - name: template_id
          in: path
          required: true
          schema:
            type: string
          description: Unique template identifier
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateFromTemplateV3Request'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/VideoDetail'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
              example:
                error:
                  code: invalid_parameter
                  message: Variable 'company_name' is not defined in this template.
                  param: variables
                  doc_url: null
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
              example:
                error:
                  code: authentication_failed
                  message: Invalid or expired API key. Verify your x-api-key header.
                  param: null
                  doc_url: null
        '404':
          description: Resource not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
              example:
                error:
                  code: template_not_found
                  message: Template not found.
                  param: null
                  doc_url: null
        '409':
          $ref: '#/components/responses/IdempotencyInProgress'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
              example:
                error:
                  code: rate_limit_exceeded
                  message: >-
                    Too many requests. Retry after the duration specified in the
                    Retry-After header.
                  param: null
                  doc_url: null
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
      security:
        - ApiKeyAuth: []
        - BearerAuth: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Optional client-supplied key for safely retrying mutations. Subsequent
        calls within 24 hours that share this key replay the original response —
        even if the request body differs slightly (a warning is logged). A retry
        that arrives while the original is still in flight gets a 409
        `request_in_progress`. Keys must be 1–255 characters from
        `[A-Za-z0-9_:.-]`; a UUID is a safe default. Scope is per-endpoint and
        per-resource: the same key on a different route or path parameter is
        independent.
      schema:
        type: string
        pattern: ^[A-Za-z0-9_\-:.]{1,255}$
        maxLength: 255
        minLength: 1
      example: 550e8400-e29b-41d4-a716-446655440000
  schemas:
    GenerateFromTemplateV3Request:
      description: Request body for POST /v3/templates/{template_id}.
      properties:
        variables:
          additionalProperties:
            discriminator:
              mapping:
                audio:
                  $ref: '#/components/schemas/TemplateAudioVariable'
                character:
                  $ref: '#/components/schemas/TemplateCharacterVariable'
                image:
                  $ref: '#/components/schemas/TemplateImageVariable'
                text:
                  $ref: '#/components/schemas/TemplateTextVariable'
                video:
                  $ref: '#/components/schemas/TemplateVideoVariable'
                voice:
                  $ref: '#/components/schemas/TemplateVoiceVariable'
              propertyName: type
            oneOf:
              - $ref: '#/components/schemas/TemplateTextVariable'
              - $ref: '#/components/schemas/TemplateImageVariable'
              - $ref: '#/components/schemas/TemplateVideoVariable'
              - $ref: '#/components/schemas/TemplateAudioVariable'
              - $ref: '#/components/schemas/TemplateCharacterVariable'
              - $ref: '#/components/schemas/TemplateVoiceVariable'
          description: >-
            Template variable replacements, keyed by the variable name defined
            in the template
          title: Variables
          type: object
        title:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Title for the generated video
          title: Title
        caption:
          default: false
          description: Whether to burn captions into the video
          title: Caption
          type: boolean
        subtitles:
          anyOf:
            - $ref: '#/components/schemas/TemplateSubtitleSettings'
            - type: 'null'
          default: null
          description: Subtitle style settings. Implies captions when provided.
        callback_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Opaque ID echoed back in webhook events for this video
          title: Callback Id
        callback_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            URL called with the video result in addition to registered webhook
            endpoints
          title: Callback Url
        folder_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Folder to place the generated video in
          title: Folder Id
        brand_voice_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Brand voice ID controlling pronunciation
          title: Brand Voice Id
        dimension:
          anyOf:
            - $ref: '#/components/schemas/TemplateVideoDimension'
            - type: 'null'
          default: null
          description: Output resolution override. Must match the template's aspect ratio.
        fps:
          default: 25
          description: Output frame rate. One of 25, 30, or 60.
          title: Fps
          type: number
        scene_ids:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          default: null
          description: >-
            Scene IDs to render, in order (repeats allowed). Scenes must already
            exist in the template; the API can select, reorder, and repeat
            scenes but cannot create new ones. Omit to render all scenes in
            template order.
          title: Scene Ids
        reorder_music:
          default: true
          description: >-
            When true (default), background audio tracks move with their scenes.
            When false, tracks stay pinned to layout positions.
          title: Reorder Music
          type: boolean
        keep_text_vertically_centered:
          default: false
          description: >-
            When true, replaced text elements are vertically re-centered based
            on their rendered height
          title: Keep Text Vertically Centered
          type: boolean
        include_gif:
          default: false
          description: Whether to include a GIF preview in the webhook payload
          title: Include Gif
          type: boolean
        enable_sharing:
          default: false
          description: Whether the generated video's share page is publicly accessible
          title: Enable Sharing
          type: boolean
      required:
        - variables
      title: GenerateFromTemplateV3Request
      type: object
    VideoDetail:
      description: |-
        Video resource returned by list and detail endpoints.

        If ``output_language`` is present the video is a translated video;
        otherwise it is a generated video.
      properties:
        id:
          description: Unique video identifier
          examples:
            - v_abc123def456
          title: Id
          type: string
        title:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Video title
          examples:
            - My Generated Video
          title: Title
        status:
          $ref: '#/components/schemas/VideoStatus'
          description: Current video status
          examples:
            - completed
        created_at:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          description: Unix timestamp of creation
          examples:
            - 1711929600
          title: Created At
        completed_at:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          description: Unix timestamp when video generation finished
          examples:
            - 1711930200
          title: Completed At
        video_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Presigned URL to download the video file
          examples:
            - https://files.heygen.ai/video/abc123.mp4
          title: Video Url
        thumbnail_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: URL to video thumbnail image
          examples:
            - https://files.heygen.ai/thumb/abc123.jpg
          title: Thumbnail Url
        gif_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: URL to animated GIF preview
          examples:
            - https://files.heygen.ai/gif/abc123.gif
          title: Gif Url
        captioned_video_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Presigned URL to download the video file with captions burned in
          examples:
            - https://files.heygen.ai/video/abc123_captioned.mp4
          title: Captioned Video Url
        subtitle_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Presigned URL to download the SRT subtitle file
          examples:
            - https://files.heygen.ai/srt/abc123.srt
          title: Subtitle Url
        duration:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Video duration in seconds
          examples:
            - 30.5
          title: Duration
        folder_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: ID of containing folder
          examples:
            - folder_abc123
          title: Folder Id
        output_language:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: BCP-47 output language code. Present only for translated videos.
          examples:
            - en-US
          title: Output Language
        failure_code:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Machine-readable failure reason. Only present when status is failed.
          examples:
            - rendering_failed
          title: Failure Code
        failure_message:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            Human-readable failure description. Only present when status is
            failed.
          examples:
            - Avatar rendering timed out
          title: Failure Message
        video_page_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: URL to the video page in the HeyGen app
          examples:
            - https://app.heygen.com/video/abc123
          title: Video Page Url
      required:
        - id
        - status
      title: VideoDetail
      type: object
    StandardAPIError:
      type: object
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: invalid_parameter
        message:
          type: string
          description: Human-readable error message
          example: Video not found
        param:
          type:
            - string
            - 'null'
          description: Which request field caused the error
        doc_url:
          type:
            - string
            - 'null'
          description: Link to error documentation
      required:
        - code
        - message
    TemplateAudioVariable:
      additionalProperties: false
      description: Replaces an audio placeholder in the template.
      properties:
        type:
          const: audio
          description: Variable type discriminator
          title: Type
          type: string
        asset:
          description: Audio to place. Accepts url, asset_id, or base64 input.
          discriminator:
            mapping:
              asset_id:
                $ref: '#/components/schemas/AssetId'
              base64:
                $ref: '#/components/schemas/AssetBase64'
              url:
                $ref: '#/components/schemas/AssetUrl'
            propertyName: type
          oneOf:
            - $ref: '#/components/schemas/AssetUrl'
            - $ref: '#/components/schemas/AssetId'
            - $ref: '#/components/schemas/AssetBase64'
          title: Asset
      required:
        - type
        - asset
      title: TemplateAudioVariable
      type: object
    TemplateCharacterVariable:
      additionalProperties: false
      description: Replaces an avatar or talking-photo placeholder in the template.
      properties:
        type:
          const: character
          description: Variable type discriminator
          title: Type
          type: string
        character_id:
          description: Avatar ID or talking photo ID to place
          minLength: 1
          title: Character Id
          type: string
        character_type:
          default: avatar
          description: Kind of character the character_id refers to
          enum:
            - avatar
            - talking_photo
          title: Character Type
          type: string
      required:
        - type
        - character_id
      title: TemplateCharacterVariable
      type: object
    TemplateImageVariable:
      additionalProperties: false
      description: Replaces an image placeholder in the template.
      properties:
        type:
          const: image
          description: Variable type discriminator
          title: Type
          type: string
        asset:
          description: Image to place. Accepts url, asset_id, or base64 input.
          discriminator:
            mapping:
              asset_id:
                $ref: '#/components/schemas/AssetId'
              base64:
                $ref: '#/components/schemas/AssetBase64'
              url:
                $ref: '#/components/schemas/AssetUrl'
            propertyName: type
          oneOf:
            - $ref: '#/components/schemas/AssetUrl'
            - $ref: '#/components/schemas/AssetId'
            - $ref: '#/components/schemas/AssetBase64'
          title: Asset
        fit:
          default: contain
          description: How the image fits the placeholder box
          enum:
            - cover
            - contain
            - crop
            - none
          title: Fit
          type: string
      required:
        - type
        - asset
      title: TemplateImageVariable
      type: object
    TemplateTextVariable:
      additionalProperties: false
      description: Replaces a text placeholder in the template.
      properties:
        type:
          const: text
          description: Variable type discriminator
          title: Type
          type: string
        content:
          description: >-
            Replacement text content. May be empty in GET responses (unfilled
            template default); must be non-empty when generating.
          maxLength: 10000
          title: Content
          type: string
      required:
        - type
        - content
      title: TemplateTextVariable
      type: object
    TemplateVideoVariable:
      additionalProperties: false
      description: Replaces a video placeholder in the template.
      properties:
        type:
          const: video
          description: Variable type discriminator
          title: Type
          type: string
        asset:
          description: Video to place. Accepts url, asset_id, or base64 input.
          discriminator:
            mapping:
              asset_id:
                $ref: '#/components/schemas/AssetId'
              base64:
                $ref: '#/components/schemas/AssetBase64'
              url:
                $ref: '#/components/schemas/AssetUrl'
            propertyName: type
          oneOf:
            - $ref: '#/components/schemas/AssetUrl'
            - $ref: '#/components/schemas/AssetId'
            - $ref: '#/components/schemas/AssetBase64'
          title: Asset
        fit:
          default: contain
          description: How the video fits the placeholder box
          enum:
            - cover
            - contain
            - crop
            - none
          title: Fit
          type: string
        play_style:
          default: loop
          description: Playback behavior when the video is shorter than the scene
          enum:
            - fit_to_scene
            - freeze
            - loop
            - once
            - full_video
          title: Play Style
          type: string
        volume:
          default: 1
          description: Audio volume of the video track, 0.0 (muted) to 1.0
          maximum: 1
          minimum: 0
          title: Volume
          type: number
      required:
        - type
        - asset
      title: TemplateVideoVariable
      type: object
    TemplateVoiceVariable:
      additionalProperties: false
      description: Overrides the voice used by a script placeholder in the template.
      properties:
        type:
          const: voice
          description: Variable type discriminator
          title: Type
          type: string
        voice_id:
          description: Voice ID used for text-to-speech
          minLength: 1
          title: Voice Id
          type: string
        locale:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Optional voice locale, e.g. 'en-US'
          title: Locale
      required:
        - type
        - voice_id
      title: TemplateVoiceVariable
      type: object
    TemplateSubtitleSettings:
      additionalProperties: false
      description: Output subtitle style settings (mirrors the /v3/videos subtitles input).
      properties:
        preset_name:
          description: Subtitle preset name, e.g. 'classic', 'bold', 'bright'
          title: Preset Name
          type: string
        alignment:
          anyOf:
            - type: integer
            - type: 'null'
          default: 2
          description: Subtitle alignment
          title: Alignment
        disable_highlight:
          anyOf:
            - type: boolean
            - type: 'null'
          default: false
          description: Override the preset's word-highlight style
          title: Disable Highlight
        font_size:
          anyOf:
            - type: integer
            - type: 'null'
          default: null
          description: Font size override for the preset
          title: Font Size
        position:
          anyOf:
            - $ref: '#/components/schemas/TemplateSubtitlePosition'
            - type: 'null'
          default: null
          description: Subtitle position override
      required:
        - preset_name
      title: TemplateSubtitleSettings
      type: object
    TemplateVideoDimension:
      additionalProperties: false
      description: Output resolution override. Must keep the template's aspect ratio.
      properties:
        width:
          description: Output video width in pixels (even number, 128-4096)
          maximum: 4096
          minimum: 128
          title: Width
          type: integer
        height:
          description: Output video height in pixels (even number, 128-4096)
          maximum: 4096
          minimum: 128
          title: Height
          type: integer
      required:
        - width
        - height
      title: TemplateVideoDimension
      type: object
    VideoStatus:
      enum:
        - pending
        - processing
        - completed
        - failed
      title: VideoStatus
      type: string
    AssetId:
      additionalProperties: false
      description: Asset input via HeyGen asset ID from the asset upload endpoint.
      properties:
        type:
          const: asset_id
          description: Input type discriminator
          title: Type
          type: string
        asset_id:
          description: HeyGen asset ID from the asset upload endpoint
          title: Asset Id
          type: string
      required:
        - type
        - asset_id
      title: AssetId
      type: object
    AssetBase64:
      additionalProperties: false
      description: Asset input via base64-encoded content.
      properties:
        type:
          const: base64
          description: Input type discriminator
          title: Type
          type: string
        media_type:
          description: MIME type of the encoded content (e.g. "image/png")
          title: Media Type
          type: string
        data:
          description: Base64-encoded file content
          title: Data
          type: string
      required:
        - type
        - media_type
        - data
      title: AssetBase64
      type: object
      x-mcp-visible: false
    AssetUrl:
      additionalProperties: false
      description: Asset input via publicly accessible HTTPS URL.
      properties:
        type:
          const: url
          description: Input type discriminator
          title: Type
          type: string
        url:
          description: Publicly accessible HTTPS URL for the asset
          title: Url
          type: string
      required:
        - type
        - url
      title: AssetUrl
      type: object
    TemplateSubtitlePosition:
      additionalProperties: false
      description: Subtitle position override.
      properties:
        x:
          default: 0
          description: Horizontal subtitle position
          title: X
          type: number
        'y':
          default: 0
          description: Vertical subtitle position
          title: 'Y'
          type: number
      title: TemplateSubtitlePosition
      type: object
  responses:
    IdempotencyInProgress:
      description: >-
        A prior request with this Idempotency-Key is still in progress. Wait for
        the original request to complete, then retry.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                $ref: '#/components/schemas/StandardAPIError'
          example:
            error:
              code: request_in_progress
              message: >-
                A request with this Idempotency-Key is already in progress.
                Retry shortly.
              param: null
              doc_url: null
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: HeyGen API key. Obtain from your HeyGen dashboard.
    BearerAuth:
      type: http
      scheme: bearer
      description: OAuth2 bearer token.

````