> ## Documentation Index
> Fetch the complete documentation index at: https://docs.samsa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Generate a video

> Submit a video job in image-to-video, text-to-video, or text-to-video-styled mode.

Submit a video-generation job. The `mode` field selects the request shape
(`image_to_video`, `text_to_video`, or `text_to_video_styled`) and the call returns
**`202 Accepted`** with a job `id`; poll
[`GET /videos/generations/{id}`](/api-reference/videos/get-generation) for the
result. Check [`GET /videos/models`](/api-reference/videos/list-engines) for each
engine's supported `duration`, `resolution`, `aspect_ratio`, end-frame, and audio
support.

## Example: image-to-video with a start and end frame

In `image_to_video` mode, `image` is the start frame and `end_image` an optional
end frame (only on end-frame-capable engines — see `supports_end_frame` in
[`GET /videos/models`](/api-reference/videos/list-engines)). Each frame takes
**exactly one** of `image_id`, `url`, or `base64` + `mime_type`.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.samsa.ai/public/v1/videos/generations \
    -H "Authorization: Bearer $SAMSA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "mode": "image_to_video",
      "image": { "url": "https://cdn.example.com/start-frame.png" },
      "end_image": { "url": "https://cdn.example.com/end-frame.png" },
      "prompt": "The camera slowly pans right as waves roll in",
      "engine": "veo_3_1_lite",
      "duration": 8,
      "aspect_ratio": "16:9",
      "resolution": "720p"
    }'
  ```

  ```json Body theme={null}
  {
    "mode": "image_to_video",
    "image": { "url": "https://cdn.example.com/start-frame.png" },
    "end_image": { "url": "https://cdn.example.com/end-frame.png" },
    "prompt": "The camera slowly pans right as waves roll in",
    "engine": "veo_3_1_lite",
    "duration": 8,
    "aspect_ratio": "16:9",
    "resolution": "720p"
  }
  ```
</CodeGroup>

<Note>
  `duration` is required and must be one the engine supports (see `durations` in
  [`GET /videos/models`](/api-reference/videos/list-engines)) — an unsupported value
  returns `422`. For `text_to_video_styled`, `style_id` is required alongside
  `prompt` and `duration`; the request body dropdown above shows all three modes.
</Note>


## OpenAPI

````yaml api-reference/openapi.json POST /videos/generations
openapi: 3.1.0
info:
  title: Samsa API
  description: >-
    The Samsa public REST API. Authenticate with an organization API key as a
    bearer token (`Authorization: Bearer samsa_sk_...`). Errors follow a single
    envelope shape; every response carries an `X-Request-ID`.
  version: 1.0.0
servers:
  - url: https://api.samsa.ai/public/v1
security:
  - BearerAuth: []
paths:
  /videos/generations:
    post:
      tags:
        - Videos
      summary: Generate a video (image-to-video, text-to-video, or styled)
      description: >-
        Submits a video-generation job and returns `202` immediately with the
        job `id` and a credit estimate; poll `GET /videos/generations/{id}` for
        the result. The `mode` field selects the workflow: `image_to_video`
        animates a start frame (`image_id`, https `url`, or
        `base64`+`mime_type`; optional `end_image` on end-frame-capable
        engines), `text_to_video` generates from a `prompt`, and
        `text_to_video_styled` combines a `prompt` with your organization's
        trained models (`style_id`, `object_ids`, `person_ids`, `setting_ids`,
        `color_palette_id`). Engines, durations, resolutions, and audio support
        are engine-specific — discover them via `GET /videos/models`. Billing:
        base 5 credits/second x engine multiplier x resolution multiplier x
        audio multiplier (styled adds a flat 10 for the intermediate image).
        Requires the `videos.generate` scope.
      operationId: create_video_generation_videos_generations_post
      parameters:
        - name: authorization
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Authorization
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: '#/components/schemas/PublicImageToVideoRequest'
                - $ref: '#/components/schemas/PublicTextToVideoRequest'
                - $ref: '#/components/schemas/PublicTextToVideoStyledRequest'
              title: Request
            examples:
              image_to_video:
                summary: Animate an image (start + end frame)
                value:
                  mode: image_to_video
                  image:
                    url: https://cdn.example.com/start-frame.png
                  end_image:
                    url: https://cdn.example.com/end-frame.png
                  prompt: The camera slowly pans right as waves roll in
                  engine: veo_3_1_lite
                  duration: 8
                  aspect_ratio: '16:9'
                  resolution: 720p
              text_to_video:
                summary: Generate a video from a prompt
                value:
                  mode: text_to_video
                  prompt: A drone shot over a foggy pine forest at sunrise
                  engine: veo_3_1
                  duration: 8
                  aspect_ratio: '16:9'
                  generate_audio: true
              text_to_video_styled:
                summary: Generate a video with your trained models
                value:
                  mode: text_to_video_styled
                  prompt: The product rotating on a marble pedestal, studio lighting
                  style_id: 11111111-1111-1111-1111-111111111111
                  setting_ids:
                    - 22222222-2222-2222-2222-222222222222
                  engine: kling_2_5_pro_turbo
                  duration: 5
                  aspect_ratio: '1:1'
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicVideoGenerationAccepted'
        '401':
          description: Missing, invalid, expired, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: Insufficient credits, or no usable org subscription.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: The API key lacks the required scope for this operation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Generation, or a referenced model/palette/image, not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: A referenced model is not ready for generation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: >-
            Request validation failed (engine, duration, resolution, frames,
            ...).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Per-key rate limit or per-org concurrency cap exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    PublicImageToVideoRequest:
      properties:
        engine:
          anyOf:
            - type: string
            - type: 'null'
          title: Engine
          description: >-
            Video engine — a public engine id from `GET /videos/models` (e.g.
            `veo_3_1_lite`, the default). Unknown engines return `422`.
          examples:
            - veo_3_1_lite
        duration:
          type: integer
          title: Duration
          description: >-
            Clip length in seconds. Each engine supports a specific set — see
            `durations` in `GET /videos/models`. Unsupported values return
            `422`.
          examples:
            - 8
        aspect_ratio:
          type: string
          title: Aspect Ratio
          description: >-
            Aspect ratio — `16:9`, `9:16`, or `1:1` (engine-dependent; see
            `aspect_ratios` in `GET /videos/models`).
          default: '16:9'
          examples:
            - '16:9'
        resolution:
          anyOf:
            - type: string
            - type: 'null'
          title: Resolution
          description: >-
            Output resolution — `720p`, `1080p`, or `4k` where the engine
            supports it (see `resolutions` in `GET /videos/models`). Omit to use
            the engine default. Credits scale with the engine's resolution
            multipliers.
          examples:
            - 720p
        generate_audio:
          type: boolean
          title: Generate Audio
          description: >-
            Generate audio with the video — audio-capable engines only (see
            `supports_audio` in `GET /videos/models`); adds the engine's audio
            credit multiplier.
          default: false
          examples:
            - false
        webhook_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Webhook Url
          description: >-
            Optional https webhook notified once on terminal status (signed per
            the webhook signature scheme; see the webhooks docs).
          examples:
            - https://example.com/webhooks/samsa
        mode:
          type: string
          const: image_to_video
          title: Mode
          default: image_to_video
        image:
          $ref: '#/components/schemas/PublicVideoFrame'
          description: >-
            The start frame: exactly one of `image_id`, `url`, or
            `base64`+`mime_type`.
        end_image:
          anyOf:
            - $ref: '#/components/schemas/PublicVideoFrame'
            - type: 'null'
          description: >-
            Optional end frame — only for end-frame-capable engines (see
            `supports_end_frame` in `GET /videos/models`).
        prompt:
          anyOf:
            - type: string
              minLength: 1
            - type: 'null'
          title: Prompt
          description: Optional text prompt guiding the motion.
          examples:
            - The camera slowly pans right as waves roll in
      type: object
      required:
        - duration
        - image
      title: PublicImageToVideoRequest
      description: '`mode: image_to_video` — animate a start frame (optional end frame).'
    PublicTextToVideoRequest:
      properties:
        engine:
          anyOf:
            - type: string
            - type: 'null'
          title: Engine
          description: >-
            Video engine — a public engine id from `GET /videos/models` (e.g.
            `veo_3_1_lite`, the default). Unknown engines return `422`.
          examples:
            - veo_3_1_lite
        duration:
          type: integer
          title: Duration
          description: >-
            Clip length in seconds. Each engine supports a specific set — see
            `durations` in `GET /videos/models`. Unsupported values return
            `422`.
          examples:
            - 8
        aspect_ratio:
          type: string
          title: Aspect Ratio
          description: >-
            Aspect ratio — `16:9`, `9:16`, or `1:1` (engine-dependent; see
            `aspect_ratios` in `GET /videos/models`).
          default: '16:9'
          examples:
            - '16:9'
        resolution:
          anyOf:
            - type: string
            - type: 'null'
          title: Resolution
          description: >-
            Output resolution — `720p`, `1080p`, or `4k` where the engine
            supports it (see `resolutions` in `GET /videos/models`). Omit to use
            the engine default. Credits scale with the engine's resolution
            multipliers.
          examples:
            - 720p
        generate_audio:
          type: boolean
          title: Generate Audio
          description: >-
            Generate audio with the video — audio-capable engines only (see
            `supports_audio` in `GET /videos/models`); adds the engine's audio
            credit multiplier.
          default: false
          examples:
            - false
        webhook_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Webhook Url
          description: >-
            Optional https webhook notified once on terminal status (signed per
            the webhook signature scheme; see the webhooks docs).
          examples:
            - https://example.com/webhooks/samsa
        mode:
          type: string
          const: text_to_video
          title: Mode
          default: text_to_video
        prompt:
          type: string
          minLength: 1
          title: Prompt
          description: >-
            Text prompt. Runs the same validation as the app (rejects empty /
            malformed / policy-violating prompts with a `422`).
          examples:
            - A drone shot over a foggy pine forest at sunrise
      type: object
      required:
        - duration
        - prompt
      title: PublicTextToVideoRequest
      description: '`mode: text_to_video` — generate a video from a prompt.'
    PublicTextToVideoStyledRequest:
      properties:
        engine:
          anyOf:
            - type: string
            - type: 'null'
          title: Engine
          description: >-
            Video engine — a public engine id from `GET /videos/models` (e.g.
            `veo_3_1_lite`, the default). Unknown engines return `422`.
          examples:
            - veo_3_1_lite
        duration:
          type: integer
          title: Duration
          description: >-
            Clip length in seconds. Each engine supports a specific set — see
            `durations` in `GET /videos/models`. Unsupported values return
            `422`.
          examples:
            - 8
        aspect_ratio:
          type: string
          title: Aspect Ratio
          description: >-
            Aspect ratio — `16:9`, `9:16`, or `1:1` (engine-dependent; see
            `aspect_ratios` in `GET /videos/models`).
          default: '16:9'
          examples:
            - '16:9'
        resolution:
          anyOf:
            - type: string
            - type: 'null'
          title: Resolution
          description: >-
            Output resolution — `720p`, `1080p`, or `4k` where the engine
            supports it (see `resolutions` in `GET /videos/models`). Omit to use
            the engine default. Credits scale with the engine's resolution
            multipliers.
          examples:
            - 720p
        generate_audio:
          type: boolean
          title: Generate Audio
          description: >-
            Generate audio with the video — audio-capable engines only (see
            `supports_audio` in `GET /videos/models`); adds the engine's audio
            credit multiplier.
          default: false
          examples:
            - false
        webhook_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Webhook Url
          description: >-
            Optional https webhook notified once on terminal status (signed per
            the webhook signature scheme; see the webhooks docs).
          examples:
            - https://example.com/webhooks/samsa
        mode:
          type: string
          const: text_to_video_styled
          title: Mode
          default: text_to_video_styled
        prompt:
          type: string
          minLength: 1
          title: Prompt
          description: Text prompt. Runs the same validation as the app.
          examples:
            - The product rotating on a marble pedestal, studio lighting
        style_id:
          type: string
          format: uuid
          title: Style Id
          description: A `style` model in your organization (must be `completed`).
        object_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Object Ids
          description: '`object` models in your organization to compose in.'
        person_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Person Ids
          description: '`person` models in your organization to compose in.'
        setting_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Setting Ids
          description: '`setting` models in your organization (maps to internal scenes).'
        color_palette_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Color Palette Id
          description: A color palette in your organization.
      type: object
      required:
        - duration
        - prompt
        - style_id
      title: PublicTextToVideoStyledRequest
      description: >-
        `mode: text_to_video_styled` — prompt + your organization's trained
        models.
    PublicVideoGenerationAccepted:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: The video job id — poll `GET /videos/generations/{id}`.
        status:
          $ref: '#/components/schemas/PublicVideoStatus'
          description: 'Initial status: always `pending` at submit.'
          examples:
            - pending
        mode:
          type: string
          title: Mode
          description: >-
            The requested mode — `image_to_video`, `text_to_video`, or
            `text_to_video_styled`.
          examples:
            - text_to_video
        estimated_credits:
          type: integer
          title: Estimated Credits
          description: >-
            Credits this job is expected to cost (base 5/sec x engine multiplier
            x resolution x audio; styled adds a flat 10 for the intermediate
            image).
          examples:
            - 80
      type: object
      required:
        - id
        - status
        - mode
        - estimated_credits
      title: PublicVideoGenerationAccepted
      description: '`202` body for `POST /videos/generations` (ADR §7.1).'
    ErrorEnvelope:
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
      type: object
      required:
        - error
      title: ErrorEnvelope
      description: The complete public error body — an ``error`` object wrapper (ADR §5).
    PublicVideoFrame:
      properties:
        image_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Image Id
          description: Id of an image in your organization's context to edit.
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
          description: https URL of the source image (downloaded under SSRF guards).
          examples:
            - https://cdn.example.com/photo.png
        base64:
          anyOf:
            - type: string
            - type: 'null'
          title: Base64
          description: Base64-encoded source image bytes (send with `mime_type`).
        mime_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Mime Type
          description: >-
            MIME type for a base64 source — one of: image/jpeg, image/png,
            image/webp.
          examples:
            - image/png
      type: object
      title: PublicVideoFrame
      description: >-
        A start or end frame for video generation — exactly one of three modes.


        Same contract as the image-edit source (SAM-556): ``image_id`` (an image
        in

        the key creator's context, ownership enforced in the route -> 404), an

        ``https`` ``url`` downloaded under the SSRF guard, or inline ``base64``
        +

        ``mime_type``. Zero or more than one mode is a ``422``.
    PublicVideoStatus:
      type: string
      enum:
        - pending
        - processing
        - completed
        - failed
        - cancelled
      title: PublicVideoStatus
      description: >-
        Public video-job status — the lower-cased internal ``VideoTaskStatus``.


        Same convention as the shipped image/models surfaces (plain lower-case,
        NOT

        the ADR §7.2 ``queued`` remap): the ticket's 202 uses ``status:
        "pending"``.
    ErrorDetail:
      properties:
        type:
          type: string
          title: Type
          examples:
            - authentication_error
        code:
          type: string
          title: Code
          examples:
            - invalid_api_key
        message:
          type: string
          title: Message
          examples:
            - The provided API key is invalid, expired, or revoked.
        request_id:
          type: string
          title: Request Id
          examples:
            - 8f14e45fceea167a5a36dedd4bea2543
        param:
          anyOf:
            - type: string
            - type: 'null'
          title: Param
          description: Present on validation errors — names the offending field.
          examples:
            - aspect_ratio
      type: object
      required:
        - type
        - code
        - message
        - request_id
      title: ErrorDetail
      description: The ``error`` object of the public envelope (ADR §5).
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Organization API key as a bearer token: `Authorization: Bearer
        samsa_sk_...`.

````