# Generate video

> Queues a video generation and returns the task straight away. Video takes minutes rather than seconds, so a webhook is the better way to hear about it than polling.

Creates a video task on the model you name. There is no `auto` and no
`count`: one request renders one video. A render takes minutes, so plan for a
[webhook](https://mynth.io/docs/concepts/webhooks.md) rather than holding a request open.

Resolution, duration, audio, and frame inputs are checked against the model at
create. [Video models](https://mynth.io/docs/models/video.md) lists what each model accepts, and
[generate video](https://mynth.io/docs/guides/generate-video.md) covers the result.

`POST /video/generate`

**Auth:** API key or OAuth token

## Request body

- `model` (required, string) — One of: `"bytedance/seedance-2.0-mini"`, `"google/gemini-omni-flash-1.1"`, `"prunaai/p-video"`, `"xai/grok-imagine-video-1.5"`. Example `"bytedance/seedance-2.0-mini"`.
- `prompt` (required, string) — Positive prompt. ≥ 1 characters, ≤ 8192 characters. Example `"A cat surfing a wave at sunset"`.
- `negative_prompt` (string) — ≤ 8192 characters.
- `duration` (number) — Video duration in seconds. Defaults to the model's default duration. ≥ 1, ≤ 60.
- `size` (object | string) — Aspect ratio and resolution tier. The aspect ratio is best effort: the closest one the model supports. With image inputs the first frame sets the shape. Defaults to "auto". One of: `"auto"`, `"square"`, `"portrait"`, `"landscape"`, `"portrait_tall"`, `"landscape_wide"`, `"1:1"`, `"2:3"`, `"3:2"`, `"3:4"`, `"4:3"`, `"4:5"`, `"5:4"`, `"9:16"`, `"16:9"`, `"21:9"`, `"2:1"`, `"1:2"`, `"auto_480p"`, `"auto_720p"`, `"auto_1080p"`, `"auto_4k"`, `"square_480p"`, `"square_720p"`, `"square_1080p"`, `"square_4k"`, `"portrait_480p"`, `"portrait_720p"`, `"portrait_1080p"`, `"portrait_4k"`, `"landscape_480p"`, `"landscape_720p"`, `"landscape_1080p"`, `"landscape_4k"`, `"portrait_tall_480p"`, `"portrait_tall_720p"`, `"portrait_tall_1080p"`, `"portrait_tall_4k"`, `"landscape_wide_480p"`, `"landscape_wide_720p"`, `"landscape_wide_1080p"`, `"landscape_wide_4k"`, `"1:1_480p"`, `"1:1_720p"`, `"1:1_1080p"`, `"1:1_4k"`, `"2:3_480p"`, `"2:3_720p"`, `"2:3_1080p"`, `"2:3_4k"`, `"3:2_480p"`, `"3:2_720p"`, `"3:2_1080p"`, `"3:2_4k"`, `"3:4_480p"`, `"3:4_720p"`, `"3:4_1080p"`, `"3:4_4k"`, `"4:3_480p"`, `"4:3_720p"`, `"4:3_1080p"`, `"4:3_4k"`, `"4:5_480p"`, `"4:5_720p"`, `"4:5_1080p"`, `"4:5_4k"`, `"5:4_480p"`, `"5:4_720p"`, `"5:4_1080p"`, `"5:4_4k"`, `"9:16_480p"`, `"9:16_720p"`, `"9:16_1080p"`, `"9:16_4k"`, `"16:9_480p"`, `"16:9_720p"`, `"16:9_1080p"`, `"16:9_4k"`, `"21:9_480p"`, `"21:9_720p"`, `"21:9_1080p"`, `"21:9_4k"`, `"2:1_480p"`, `"2:1_720p"`, `"2:1_1080p"`, `"2:1_4k"`, `"1:2_480p"`, `"1:2_720p"`, `"1:2_1080p"`, `"1:2_4k"`.
  - **auto**
    - `type` (required, "auto")
    - `resolution` (string) — Resolution tier. Each model supports a subset, and a tier it does not support is rejected. Defaults to the model's default tier. One of: `"480p"`, `"720p"`, `"1080p"`, `"4k"`.
  - **aspect_ratio**
    - `type` (required, "aspect_ratio")
    - `aspect_ratio` (required, string) — One of: `"1:1"`, `"2:3"`, `"3:2"`, `"3:4"`, `"4:3"`, `"4:5"`, `"5:4"`, `"9:16"`, `"16:9"`, `"21:9"`, `"2:1"`, `"1:2"`.
    - `resolution` (string) — Resolution tier. Each model supports a subset, and a tier it does not support is rejected. Defaults to the model's default tier. One of: `"480p"`, `"720p"`, `"1080p"`, `"4k"`.
- `audio` (boolean) — Enable model-native generated audio. Only supported by models with audio capability.
- `inputs` ((string | object)[]) — ≤ 5 items.
  - **type + source**
    - `type` (required, "image")
    - `as` (string) — One of: `"auto"`, `"first_frame"`, `"last_frame"`, `"reference"`.
    - `source` (required, object)
      - `type` (required, "url")
      - `url` (required, string) — format: uri.
- `generate_public_access_token` (boolean) — Return a short-lived public access token as `public_access_token`, for polling this task from browser code without your API key. Defaults to false.
- `webhook` (object)
  - `registered` (boolean) — Set to false to skip the webhooks registered on the account for this task. Custom webhooks in `custom` are still sent.
  - `custom` (object[]) — ≥ 1 items, ≤ 5 items.
    - `url` (required, string) — Receives this task's events, unsigned. Use https and a public host, and put a secret token in the query string to verify deliveries: only `scheme://host` is ever shown back. Example `"https://example.com/hooks/mynth?token=your-secret-token"`.
- `metadata` (object)

## Response

### 201 — Video generation task created

- `data` (required, object)
  - `task_id` (required, string) — Task ID Example `"tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP"`.
  - `estimated_cost` (required, string) — Estimated cost in USD reserved for this task. Work that fails is refunded, so the final cost may be lower. Example `"0.03"`.
  - `public_access_token` (string) — Short-lived public access token for polling this task's status and result. Safe to hand to browser code instead of your API key. Returned only when the request set `generate_public_access_token: true`. Example `"pat_eyJhbGciOi..."`.

```json
{
  "data": {
    "task_id": "tsk_01KE7XWWEQ4MCGWKBQKJ1G47RP",
    "estimated_cost": "0.03",
    "public_access_token": "pat_eyJhbGciOi..."
  }
}
```

### 400 — The request was rejected before anything was queued. `error.message` says what to change. A field that failed the schema, or one the endpoint does not take, is also listed in `error.issues`.

- `error` (required, object)
  - `code` (required, string) — `validation_error` for a body that failed validation, `invalid_json` for one that is not JSON. One of: `"validation_error"`, `"invalid_json"`.
  - `message` (required, string) — Every problem, in one sentence each, led by the field it is about.
  - `issues` (object[]) — One entry per field that failed the schema, and one per field the endpoint does not take.
    - `path` (required, (string | integer)[]) — Where the problem is, e.g. `["inputs", 0, "source"]`. Empty for the body as a whole.
    - `message` (required, string)

```json
{
  "error": {
    "code": "validation_error",
    "message": "count: Too big: expected number to be <=20. colour: Unknown field.",
    "issues": [
      {
        "path": [
          "count"
        ],
        "message": "Too big: expected number to be <=20"
      },
      {
        "path": [
          "colour"
        ],
        "message": "Unknown field."
      }
    ]
  }
}
```

## Request samples

### cURL

```bash
curl -X POST https://api.mynth.io/video/generate \
  -H "Authorization: Bearer $MYNTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bytedance/seedance-2.0-mini",
    "prompt": "A cat surfing a wave at sunset"
  }'
```

### JavaScript

```ts
const response = await fetch("https://api.mynth.io/video/generate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MYNTH_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "bytedance/seedance-2.0-mini",
    "prompt": "A cat surfing a wave at sunset"
  }),
});

const { data } = await response.json();
```

The full schema for this endpoint is in the [OpenAPI document](https://api.mynth.io/openapi.json).
