> ## 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.

# Get Video Scenes

> Returns the video's scenes together with the video-level context needed to use them, read together rather than assembled from separate calls. Describes the video as it stands now, including any edits made in the editor after it was created. The scene list is never paginated.

Each scene splits by the role a thing plays: `background` fills the frame, `elements` are placed within it, and `script` is the audio delivered over it. A whole-frame image or clip lands in `background`, so code that reads only `elements` misses it.

Element types are an open set: treat an unrecognized type as an element to skip rather than an error, and expect a type value to become more specific over time. Every element a scene places appears in `elements`, so the count is always truthful, but only `avatar`, `image` and `video` are described in full; `group` and `mask` carry their children; the rest carry an `id` and a `type` and nothing more.

**What this does not describe.** A video may contain more than this response expresses, and a video rebuilt from it will differ in these respects: element geometry (position, size, opacity); the text inside a text element; scene and element animations and scene effects; per-scene caption styling, where only whether captions are enabled is reported; background audio, which is video-level and belongs to no scene, so a rebuild loses the music; and some per-avatar values, which are withheld to keep this version small and are returned on request.



## OpenAPI

````yaml /openapi/external-api.json get /v3/videos/{video_id}/scenes
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: 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
  - name: Filler Word Removal
    description: ''
paths:
  /v3/videos/{video_id}/scenes:
    get:
      tags:
        - Videos
      summary: Get Video Scenes
      description: >-
        Returns the video's scenes together with the video-level context needed
        to use them, read together rather than assembled from separate calls.
        Describes the video as it stands now, including any edits made in the
        editor after it was created. The scene list is never paginated.


        Each scene splits by the role a thing plays: `background` fills the
        frame, `elements` are placed within it, and `script` is the audio
        delivered over it. A whole-frame image or clip lands in `background`, so
        code that reads only `elements` misses it.


        Element types are an open set: treat an unrecognized type as an element
        to skip rather than an error, and expect a type value to become more
        specific over time. Every element a scene places appears in `elements`,
        so the count is always truthful, but only `avatar`, `image` and `video`
        are described in full; `group` and `mask` carry their children; the rest
        carry an `id` and a `type` and nothing more.


        **What this does not describe.** A video may contain more than this
        response expresses, and a video rebuilt from it will differ in these
        respects: element geometry (position, size, opacity); the text inside a
        text element; scene and element animations and scene effects; per-scene
        caption styling, where only whether captions are enabled is reported;
        background audio, which is video-level and belongs to no scene, so a
        rebuild loses the music; and some per-avatar values, which are withheld
        to keep this version small and are returned on request.
      operationId: getVideoScenesV3
      parameters:
        - name: video_id
          in: path
          required: true
          schema:
            type: string
          description: Unique video identifier
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type:
                      - object
                      - 'null'
                    default: null
                  data:
                    $ref: '#/components/schemas/VideoScenesResponse'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    $ref: '#/components/schemas/StandardAPIError'
              example:
                error:
                  code: unauthorized
                  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: not_found
                  message: Video not found.
                  param: null
                  doc_url: null
        '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:
  schemas:
    VideoScenesResponse:
      additionalProperties: false
      description: 'The composite document: one video''s context and every one of its scenes.'
      properties:
        video_id:
          description: The video these scenes belong to.
          title: Video Id
          type: string
        video:
          $ref: '#/components/schemas/VideoContext'
          description: Video-level context for the scenes.
        scenes:
          description: >-
            Every scene in the video, in the video's own order, which is
            playback order unless the video branches. Never paginated.
          items:
            $ref: '#/components/schemas/Scene'
          title: Scenes
          type: array
      required:
        - video_id
        - video
      title: VideoScenesResponse
      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
        errors:
          type: array
          description: >-
            Per-item error details for batch/multi-node failures (e.g. graph
            compilation errors by node).
          items:
            $ref: '#/components/schemas/StandardAPIErrorDetail'
      required:
        - code
        - message
    VideoContext:
      additionalProperties: false
      description: >-
        Video-level facts needed to make sense of the scenes.


        Returned together with the scenes rather than left to a second call,
        because

        assembling them from two reads of mutable state is not atomic: a human
        edit landing

        between the two yields new scenes paired with an old aspect ratio.
      properties:
        title:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: The video's current title. Editor saves update it.
          title: Title
        aspect_ratio:
          anyOf:
            - $ref: '#/components/schemas/VideoAspectRatio'
            - type: 'null'
          default: null
          description: The video's aspect ratio.
        resolution:
          anyOf:
            - $ref: '#/components/schemas/VideoResolution'
            - type: 'null'
          default: null
          description: >-
            The video's output resolution, in the same values a create request
            accepts. Absent when the video's stored size matches no such value,
            which is a video whose size a create request could not have asked
            for and cannot reproduce.
        caption:
          anyOf:
            - $ref: '#/components/schemas/VideoCaption'
            - type: 'null'
          default: null
          description: Caption configuration for the video.
        brand_glossary_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Brand glossary applied to this video's speech.
          title: Brand Glossary Id
      title: VideoContext
      type: object
    Scene:
      additionalProperties: false
      description: >-
        One scene, in the video's own order.


        That is playback order for a linear video, which is the ordinary case. A
        branching video plays as

        a walk over branch targets instead, so its scenes are still all here and
        still ordered, but the

        order is not the sequence a viewer sees. Branching is not otherwise
        described by this version.


        The three content fields split by the role a thing plays rather than by
        its kind:

        ``background`` fills the frame, ``elements`` are placed within it,
        ``script`` carries

        the speech delivered over it. The background is visual too, so
        ``elements`` means "the

        ones the scene places", not "the visual ones".
      properties:
        id:
          description: Identifier of this scene within the video.
          title: Id
          type: string
        background:
          anyOf:
            - discriminator:
                mapping:
                  color:
                    $ref: '#/components/schemas/ColorBackground'
                  image:
                    $ref: '#/components/schemas/ImageBackground'
                  video:
                    $ref: '#/components/schemas/VideoBackground'
                propertyName: type
              oneOf:
                - $ref: '#/components/schemas/ColorBackground'
                - $ref: '#/components/schemas/ImageBackground'
                - $ref: '#/components/schemas/VideoBackground'
            - type: 'null'
          default: null
          description: What fills the frame behind this scene's elements.
          title: Background
        elements:
          description: Every element this scene places, in the video's own order.
          items:
            anyOf:
              - $ref: '#/components/schemas/AvatarElement'
              - $ref: '#/components/schemas/ImageElement'
              - $ref: '#/components/schemas/VideoElement'
              - $ref: '#/components/schemas/PlaceholderElement'
              - $ref: '#/components/schemas/ContainerElement'
          title: Elements
          type: array
        script:
          description: >-
            This scene's audio sources in order, each one synthesized speech,
            uploaded audio, or a silence. The create API's per-scene `script` is
            narrower: it is the text of a single one of these entries.
          items:
            anyOf:
              - $ref: '#/components/schemas/TextScriptEntry'
              - $ref: '#/components/schemas/AudioScriptEntry'
              - $ref: '#/components/schemas/SilenceScriptEntry'
          title: Script
          type: array
      required:
        - id
      title: Scene
      type: object
    StandardAPIErrorDetail:
      type: object
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: unknown_node_type
        message:
          type: string
          description: Human-readable error message
          example: Unknown node type
        node_id:
          type: string
          description: Graph node id this error pertains to, if applicable
        port:
          type: string
          description: Port name on the node this error pertains to, if applicable
        path:
          type: string
          description: Field path within the item this error pertains to, if applicable
      required:
        - code
        - message
    VideoAspectRatio:
      description: >-
        Output video aspect ratio.


        - ``16:9`` / ``9:16``: classic landscape / portrait.

        - ``4:5`` / ``5:4`` / ``1:1``: social-media-friendly ratios. Output is
        short-edge anchored to
          the requested resolution (e.g. ``1080p`` 1:1 → 1080x1080, ``1080p`` 4:5 → 1080x1350).
        - ``auto``: preserve the source's aspect ratio. The dimensions are
        derived from the avatar's
          source frames (``avatar_id``) or the uploaded image (``image_url`` / ``image_asset_id``),
          short-edge anchored to the requested resolution and capped at the tier's long edge.
          Falls back to ``16:9`` when source dimensions can't be read.
      enum:
        - '16:9'
        - '9:16'
        - '4:5'
        - '5:4'
        - '1:1'
        - auto
      title: VideoAspectRatio
      type: string
    VideoResolution:
      description: Output video resolution.
      enum:
        - 4k
        - 1080p
        - 720p
      title: VideoResolution
      type: string
    VideoCaption:
      additionalProperties: false
      description: Whether the video involves captions.
      properties:
        enabled:
          description: Whether captions are enabled for this video.
          title: Enabled
          type: boolean
      required:
        - enabled
      title: VideoCaption
      type: object
    ColorBackground:
      additionalProperties: false
      description: A solid colour filling the frame behind the scene's elements.
      properties:
        type:
          const: color
          default: color
          description: Background type discriminator.
          title: Type
          type: string
        color:
          description: Hex colour, e.g. '#f6f6fc'.
          title: Color
          type: string
      required:
        - color
      title: ColorBackground
      type: object
    ImageBackground:
      additionalProperties: false
      description: A whole-frame image.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          const: image
          default: image
          description: Background type discriminator.
          title: Type
          type: string
        url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: URL of the image. Absent when no durable link is available.
          title: Url
      required:
        - id
      title: ImageBackground
      type: object
    VideoBackground:
      additionalProperties: false
      description: A whole-frame video clip.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          const: video
          default: video
          description: Background type discriminator.
          title: Type
          type: string
        url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: URL of the clip. Absent when no durable link is available.
          title: Url
        playback:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            How the clip is reconciled to the scene. Same values as a video
            element's playback.
          title: Playback
        trim:
          anyOf:
            - $ref: '#/components/schemas/VideoTrim'
            - type: 'null'
          default: null
          description: Seconds trimmed from each end of the clip.
        volume:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Clip audio volume. 1.0 = source level, 0.0 = silent.
          title: Volume
        speed_multiplier:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Playback speed multiplier. 2.0 = twice as fast.
          title: Speed Multiplier
      required:
        - id
      title: VideoBackground
      type: object
    AvatarElement:
      additionalProperties: false
      description: >-
        An avatar performing the scene's speech.


        **This is a deliberately minimal set, not everything the video records
        about an avatar.** It

        covers what a v3 create request can set per avatar, so what is read back
        is what can be sent

        back. A video may hold further per-avatar values — including some an
        older create surface

        accepts per character — and those are not returned in this version. The
        set grows additively as

        callers ask for a value, so a field appearing later is not a breaking
        change.


        Resolution is the omission worth naming, because one is returned but not
        here: a v3 create

        carries a single global resolution, so it is reported on the video. That
        video-level value is

        the request's own output resolution and **not** a summary of what the
        avatars hold — on a video

        whose avatars were given resolutions individually, the two are separate
        inputs and can differ.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          const: avatar
          default: avatar
          description: Element type discriminator.
          title: Type
          type: string
        avatar_id:
          description: The avatar look performing this scene.
          title: Avatar Id
          type: string
        engine:
          anyOf:
            - $ref: '#/components/schemas/AvatarEngineTier'
            - type: 'null'
          default: null
          description: >-
            Generation engine for this avatar. Absent when the video does not
            record one and none can be determined.
        expressiveness:
          anyOf:
            - $ref: '#/components/schemas/Expressiveness'
            - type: 'null'
          default: null
          description: Expressiveness level. Absent when left at the default.
        motion_prompt:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Motion description authored for this avatar.
          title: Motion Prompt
      required:
        - id
        - avatar_id
      title: AvatarElement
      type: object
    ImageElement:
      additionalProperties: false
      description: An image placed in the scene.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          const: image
          default: image
          description: Element type discriminator.
          title: Type
          type: string
        url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            URL of the image. Absent when no durable link is available — the
            stored link is an expired signature and there is no current one to
            re-sign from. Present, it is not guaranteed to resolve: it may point
            at a host the customer supplied, and a signed link expires. An image
            with no URL carries only its id and type, which is an image this
            read could not link to rather than an element this API does not
            describe.
          title: Url
      required:
        - id
      title: ImageElement
      type: object
    VideoElement:
      additionalProperties: false
      description: A video clip placed in the scene.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          const: video
          default: video
          description: Element type discriminator.
          title: Type
          type: string
        url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            URL of the clip. Absent when no durable link is available — the
            stored link is an expired signature and there is no current one to
            re-sign from. Present, it is not guaranteed to resolve: it may point
            at a host the customer supplied, and a signed link expires.
          title: Url
        playback:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            How the clip is reconciled to the scene: 'freeze' holds the last
            frame, 'loop' repeats it, 'fit_to_scene' changes speed to match,
            'full_video' plays it whole and drives the scene's length.
          title: Playback
        trim:
          anyOf:
            - $ref: '#/components/schemas/VideoTrim'
            - type: 'null'
          default: null
          description: Seconds trimmed from each end of the clip.
        volume:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Clip audio volume. 1.0 = source level, 0.0 = silent.
          title: Volume
        speed_multiplier:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Playback speed multiplier. 2.0 = twice as fast.
          title: Speed Multiplier
      required:
        - id
      title: VideoElement
      type: object
    PlaceholderElement:
      additionalProperties: false
      description: >-
        An element this version names but does not describe.


        Exists so a scene's ``elements`` array is never a filtered view
        presented as a complete one: a

        caller iterating it sees every element the scene places. Carries exactly
        two fields: which

        element this is, and what kind of thing it is. The absence of content
        fields is the assertion,

        so nothing has to be added when a category graduates to being described.


        **Absence of content is not by itself proof that an element is
        undescribed.** A described

        category can serialize with nothing but an id and a type when every
        optional field happens to be

        unavailable, and one case is reachable today: an image whose stored link
        is a signature this read

        could not renew carries no ``url``, leaving ``{id, type}``. Read the
        ``type`` to tell them apart.

        ``avatar``, ``image`` and ``video`` are described, so a bare one of
        those is a described element

        missing an optional value rather than an unexpanded node.


        The ``id`` matters most here. Two masked elements in one scene are
        otherwise identical on the

        wire, so without it a caller can see that the scene places two things
        and nothing else about

        either.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          description: >-
            The element's category. An **open set**: new values may be added, so
            treat an unrecognized one as an element to skip rather than an
            error. Several kinds of element can share one value, so a category
            identifies what an element is rather than how it is stored. Every
            value is permanent except 'other', which means 'a kind of element
            this API does not yet categorise' and may be replaced by a more
            specific category later.
          title: Type
          type: string
      required:
        - id
        - type
      title: PlaceholderElement
      type: object
    ContainerElement:
      additionalProperties: false
      description: >-
        An element that holds other elements: a group, or a mask.


        Returned as a node with its children under it, because the scene does
        not list those children

        itself — a scene holding one group of five images lists one element
        while five things render.

        Omitting the container would erase its contents rather than merely its
        label, and flattening the

        children up into the scene's own list would rebuild the draft's flat,
        pointer-based layout on the

        public surface, which is the thing this tree exists to spare a caller.


        A caller walking a scene's composition therefore has to recurse. A mask
        matters more than a group

        here: a group conveys linkage this response does not express, while a
        mask conveys clipping, so

        presenting a masked image as a plain image would assert a composition
        that renders differently in

        kind.
      properties:
        id:
          description: >-
            Opaque identifier of this element within the video. Not to be
            parsed, sorted, or assumed to encode anything. Minted once when the
            video's editor document is created, and stable across edits and
            regeneration.
          title: Id
          type: string
        type:
          description: The container's category, e.g. 'group' or 'mask'.
          title: Type
          type: string
        children:
          description: >-
            The elements this container holds, each described exactly as a
            top-level element would be.
          items:
            anyOf:
              - $ref: '#/components/schemas/AvatarElement'
              - $ref: '#/components/schemas/ImageElement'
              - $ref: '#/components/schemas/VideoElement'
              - $ref: '#/components/schemas/PlaceholderElement'
              - $ref: '#/components/schemas/ContainerElement'
          title: Children
          type: array
      required:
        - id
        - type
      title: ContainerElement
      type: object
    TextScriptEntry:
      additionalProperties: false
      description: 'Synthesized speech: a script delivered by a voice.'
      properties:
        id:
          description: >-
            Opaque identifier of this script entry within the video. Not to be
            parsed, sorted, or assumed to encode anything. The same id under two
            scenes means one entry is shared between them: its text belongs to
            both, and concatenating both scenes' scripts would synthesize the
            shared words twice.
          title: Id
          type: string
        type:
          const: text
          default: text
          description: Script entry type discriminator.
          title: Type
          type: string
        text:
          description: >-
            The script, verbatim, including inline markup. Empty when the scene
            was left unfinished.
          title: Text
          type: string
        voice_id:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: The voice delivering this script.
          title: Voice Id
        voice_settings:
          anyOf:
            - $ref: '#/components/schemas/ScriptVoiceSettings'
            - type: 'null'
          default: null
          description: Voice tuning applied to this script.
        trim_to_speech:
          anyOf:
            - type: boolean
            - type: 'null'
          default: null
          description: >-
            Whether leading and trailing silence is trimmed to the spoken
            window.
          title: Trim To Speech
      required:
        - id
        - text
      title: TextScriptEntry
      type: object
    AudioScriptEntry:
      additionalProperties: false
      description: Uploaded audio played as the scene's speech.
      properties:
        id:
          description: Identifier of this script entry within the video.
          title: Id
          type: string
        type:
          const: audio
          default: audio
          description: Script entry type discriminator.
          title: Type
          type: string
        audio_url:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: >-
            URL of the audio. Absent when no durable link is available — the
            stored link is an expired signature and there is no current one to
            re-sign from. Present, it is not guaranteed to resolve: it may point
            at a host the customer supplied, and a signed link expires.
          title: Audio Url
      required:
        - id
      title: AudioScriptEntry
      type: object
    SilenceScriptEntry:
      additionalProperties: false
      description: A held silence, with no words spoken over the scene.
      properties:
        id:
          description: Identifier of this script entry within the video.
          title: Id
          type: string
        type:
          const: silence
          default: silence
          description: Script entry type discriminator.
          title: Type
          type: string
        duration:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: >-
            How long the silence is held, in seconds. Absent where the number
            does not describe what renders — on a scene whose video clip plays
            in full, the clip's own length governs the scene.
          title: Duration
      required:
        - id
      title: SilenceScriptEntry
      type: object
    VideoTrim:
      additionalProperties: false
      description: Seconds trimmed from each end of a clip.
      properties:
        start_offset:
          description: Seconds trimmed from the start of the clip.
          title: Start Offset
          type: number
        end_offset:
          description: Seconds trimmed from the end of the clip.
          title: End Offset
          type: number
      required:
        - start_offset
        - end_offset
      title: VideoTrim
      type: object
    AvatarEngineTier:
      description: >-
        Coarse UI-facing tier. This is what the user sees in the engine
        dropdown.
      enum:
        - avatar_v
        - avatar_iv
        - avatar_iii
      title: AvatarEngineTier
      type: string
    Expressiveness:
      description: Avatar expressiveness level for photo avatars.
      enum:
        - high
        - medium
        - low
      title: Expressiveness
      type: string
    ScriptVoiceSettings:
      additionalProperties: false
      description: >-
        The voice tuning a customer can set, and only that.


        Deliberately not the request-side ``VoiceSettingsInput``: that model
        constrains

        each field to the range the create API accepts (e.g. speed 0.5–1.5), and
        a draft

        can legitimately hold a value outside it that an editor user chose.
        Reusing the

        request model would reject a video we are only describing.
      properties:
        speed:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Playback speed multiplier.
          title: Speed
        pitch:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Pitch adjustment in semitones.
          title: Pitch
        volume:
          anyOf:
            - type: number
            - type: 'null'
          default: null
          description: Voice audio volume. 1.0 = full, 0.0 = silent.
          title: Volume
        locale:
          anyOf:
            - type: string
            - type: 'null'
          default: null
          description: Locale/accent hint for multi-lingual voices (e.g. 'en-US').
          title: Locale
        engine_settings:
          anyOf:
            - discriminator:
                mapping:
                  elevenlabs:
                    $ref: '#/components/schemas/ElevenLabsEngineSettings'
                  fish:
                    $ref: '#/components/schemas/FishEngineSettings'
                  starfish:
                    $ref: '#/components/schemas/StarfishEngineSettings'
                propertyName: engine_type
              oneOf:
                - $ref: '#/components/schemas/ElevenLabsEngineSettings'
                - $ref: '#/components/schemas/FishEngineSettings'
                - $ref: '#/components/schemas/StarfishEngineSettings'
            - type: 'null'
          default: null
          description: >-
            Engine-specific voice tuning, discriminated by 'engine_type'.
            Present only when the video pins an engine this API exposes; absent
            when the engine is left for the server to pick.
          title: Engine Settings
      title: ScriptVoiceSettings
      type: object
    ElevenLabsEngineSettings:
      description: >-
        Engine-specific voice settings for ElevenLabs-backed voices.


        Supports model, stability, similarity_boost, style, and
        use_speaker_boost.

        When using eleven_v3, stability must be 0, 0.5, or 1.
      properties:
        model:
          anyOf:
            - $ref: '#/components/schemas/ElevenLabsModel'
            - type: 'null'
          default: null
          description: The model ID to use for ElevenLabs.
        similarity_boost:
          anyOf:
            - maximum: 1
              minimum: 0
              type: number
            - type: 'null'
          default: null
          description: The similarity boost parameter for ElevenLabs.
          title: Similarity Boost
        stability:
          anyOf:
            - maximum: 1
              minimum: 0
              type: number
            - type: 'null'
          default: null
          description: The stability parameter for ElevenLabs.
          title: Stability
        style:
          anyOf:
            - maximum: 1
              minimum: 0
              type: number
            - type: 'null'
          default: null
          description: The style parameter for ElevenLabs.
          title: Style
        use_speaker_boost:
          anyOf:
            - type: boolean
            - type: 'null'
          default: null
          description: Whether to use speaker boost for ElevenLabs.
          title: Use Speaker Boost
        engine_type:
          const: elevenlabs
          description: >-
            Engine type discriminator. Must be 'elevenlabs' for
            ElevenLabs-backed voices.
          title: Engine Type
          type: string
      required:
        - engine_type
      title: ElevenLabsEngineSettings
      type: object
    FishEngineSettings:
      description: |-
        Engine-specific voice settings for Fish Audio-backed voices.

        Inherits Fish's tuning fields (model, stability, similarity).
      properties:
        model:
          anyOf:
            - $ref: '#/components/schemas/FishModel'
            - type: 'null'
          default: null
          description: Fish Audio model version (default 's1').
        stability:
          anyOf:
            - maximum: 1
              minimum: 0
              type: number
            - type: 'null'
          default: null
          description: Stability parameter; higher is more consistent.
          title: Stability
        similarity:
          anyOf:
            - maximum: 1
              minimum: 0
              type: number
            - type: 'null'
          default: null
          description: Similarity parameter; how closely to match the source voice.
          title: Similarity
        engine_type:
          const: fish
          description: >-
            Engine type discriminator. Must be 'fish' for Fish Audio-backed
            voices.
          title: Engine Type
          type: string
      required:
        - engine_type
      title: FishEngineSettings
      type: object
    StarfishEngineSettings:
      description: >-
        Engine-selection for Starfish-backed voices.


        Starfish has no user-tunable settings today; set
        ``engine_type='starfish'`` to force

        Starfish routing on voices that support multiple engines.
      properties:
        engine_type:
          const: starfish
          description: >-
            Engine type discriminator. Must be 'starfish' for Starfish-backed
            voices.
          title: Engine Type
          type: string
      required:
        - engine_type
      title: StarfishEngineSettings
      type: object
    ElevenLabsModel:
      description: >-
        ElevenLabs model IDs exposed on the public API.


        Only current models are included — deprecated models (monolingual_v1,
        multilingual_v1,

        turbo_v2) are not accepted.
      enum:
        - eleven_multilingual_v2
        - eleven_turbo_v2_5
        - eleven_flash_v2_5
        - eleven_v3
      title: ElevenLabsModel
      type: string
    FishModel:
      description: Fish Audio model version.
      enum:
        - s1
        - s2-pro
      title: FishModel
      type: string
  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.

````