---
title: "Generate Video"
method: POST
path: "/media/generate-video"
tags: ["media"]
---

# Generate Video

`POST /media/generate-video`

## Request

- Base URL: `https://api.moda.app/v1`
- URL: `https://api.moda.app/v1/media/generate-video`
- Auth: HTTP bearer

Generate one short video (metered).

``wait`` (default true) runs the provider render inside this call, which takes 30-300s.
``wait: false`` returns as soon as the render is submitted, with a ``task_id`` and a
``poll_url``; poll it about every ``retry_after_ms`` until ``status`` is terminal. Nothing is
charged at submission — the charge lands when a poll collects the finished video, so an
abandoned task costs nothing.

## Headers

- `Moda-Version` '2026-04-12' | '2026-05-01'

## Request body

- GenerateVideoRequest
  - `prompt` string, required: Sent verbatim. For MiniMax H3 reference mode, bind inputs by modality and 1-based list order: Image 1, Video 1, Audio 1, and so on.
  - `model` string, required: Concrete video model id; see GET /v1/media/models.
  - `start_image` string, nullable
  - `end_image` string, nullable
  - `reference_images` string[], nullable: Subject/style references. For MiniMax H3, name them Image 1, Image 2, and so on in the prompt.
  - `reference_videos` string[], nullable: Short reference clips: file_ ids from an upload or http(s) video URLs. Only some models accept them, and each states its own clip-count and length limits — read them off the `reference_videos` block on GET /v1/media/models, which a 422 also names in full. Naming the models here instead would drift on every model add. Each clip becomes a durable file in the team's library; the model card states whether its running time is billed too. For MiniMax H3, name them Video 1, Video 2, and so on in the prompt.
  - `reference_audios` string[], nullable: Short reference audio: file_ ids from an upload or http(s) audio URLs. See the reference_audios capability on GET /v1/media/models. For MiniMax H3, name them Audio 1, Audio 2, and so on in the prompt.
  - `extend_video` string, nullable: Make an EXISTING clip longer: a file_ id from an upload or an http(s) video URL, plus a prompt for what happens next. The response carries the source with new footage on the end. Only models whose card lists a `video_extend` mode accept it, and it cannot be combined with start/end frames or references. There `duration_seconds` is the length of the ADDED segment — the delivered clip is longer than it by the source's own running time. Read `billing.duration_quantity` and `billing.input_seconds_priced_separately`, plus the available framing controls, from the `video_extend` block on GET /v1/media/models.
  - `lipsync_video` string, nullable: Re-cut an EXISTING clip's mouth to a track you supply: a file_ id from an upload or an http(s) video URL, plus exactly one `reference_audios` entry — the speech being synced to. Only models whose card lists a `video_lipsync` mode accept it. Nothing else may accompany the pair: no frames, no other references, and not `extend_video`. The clip is returned at its OWN length, so `duration_seconds` is not a control here and `prompt` is not used at all. Billing meters the SOURCE clip rather than the returned file — read the `video_lipsync` block on GET /v1/media/models for its envelope, its basis, and any block rounding.
  - `duration_seconds` union
    - number
    - string
  - `aspect_ratio` string, nullable
  - `width` integer, nullable
  - `height` integer, nullable
  - `resolution` string, nullable: Resolution tier from the selected mode's resolutions on GET /v1/media/models.
  - `generate_audio` boolean, nullable
  - `seed` integer, nullable
  - `model_params` object, nullable
  - `idempotency_key` string, nullable: Keys the provider-job checkpoint: a retried call with the same key resumes the existing render instead of paying for a duplicate.
  - `wait` boolean: Whether the provider render runs inside this call. The default holds the request open for the whole render (30-300s). Pass false to get a task envelope back immediately and poll GET /v1/media/generate-video/{task_id} — the right choice for long renders and for starting several candidates at once. Nothing is charged until a poll collects the finished video.

## Response `200`

Successful Response

- object

## Other responses

- `401`: Authentication required.
- `402`: Insufficient credits for a metered operation.
- `403`: Permission denied for this scope.
- `404`: Resource not found.
- `409`: Conflict (idempotency / resource state).
- `422`: Request validation failed.
- `429`: Rate limit exceeded.
- `500`: Internal error.

## Changes

- **2026-11-03** `9ac6a3abc0f8`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/moda/apis/moda-public-api/changes/media/generate-video/post.md)

---

[API](https://skmtc.dev/moda/apis/moda-public-api.md) - [All operations](https://skmtc.dev/moda/apis/moda-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/moda/apis/moda-public-api/revisions/9ac6a3abc0f8?raw)
