# Input fields

Every model reads the same field names, so a request keeps its shape when you change model. Send only the fields the model lists in its `params` (`GET /v1/models/{id}`): any other field is refused with `400`, never silently dropped.

| Field | Type | Limits | What it is |
| - | - | - | - |
| `prompt` | string | 20,000 characters | What to make. |
| `negative_prompt` | string | 5,000 characters | What to avoid. |
| `images` | array of files | 16 per call, or the model's `max` | Reference images. A first frame or main reference goes first. |
| `end_image` | file | | The last frame, for models that take one. |
| `video` | file | | A reference or source clip. Its seconds are billed too, see [Billing](/vidlab-api/docs/billing#reference-video). |
| `audio` | file | | A source sound (lip sync, speech to video). |
| `duration` | number | The model's `min` and `max`, or its `values` | Seconds of output. For lip sync and similar models, see [Length from a file](#length-from-a-file). |
| `resolution` | string | The model's `values` | For example `720p` or `2k`. |
| `aspect_ratio` | string | The model's `values` | For example `9:16`, `1:1`, `16:9`. |
| `quality` | string | The model's `values` | For example `turbo` or `quality`. |
| `generate_audio` | boolean | | Ask for sound where the model makes it. Selects the `+audio` price. |
| `seed` | integer | | Repeatable results where the model supports it. |
| `n` | integer | 1 to 10, or the model's `max` | How many images. |
| `text` | string | 20,000 characters | Text to speak, for voice models. |
| `voice` | string | | A voice id or name, for voice models. |
| `extra` | object | 8 KB as JSON | Model-specific options. Only the keys a model allows are used. |

Every model's page has an API reference for each task it does: the endpoint, a request for that model in cURL, Python and JavaScript, and this table filled in with the model's own fields and limits.

Options differ by model. Read a model's `params` (`GET /v1/models/{id}`) or open it on the [models page](/vidlab-api/models): `seedance-2.5`, for example, lists `resolution`, `duration` with its `min` and `max`, `aspect_ratio`, up to 16 `images` and a reference `video`.

A **file** is a public https link, a link from [Uploads](/vidlab-api/docs/uploads), or a small base64 data URL. Values are matched without regard to letter case (`720P` reads as `720p`). A field that changes the price and is left out gets the model's first allowed value, so the quote and the run always agree.

## What a bad input answers

A request that breaks a model's `params` is refused before anything is held. The message names the field and says what is allowed.

| You sent | Answer |
| - | - |
| A field the model does not take | `400 invalid_input`: "`n` is not an option of this model. It takes: resolution, prompt, images, ..." |
| A name that is not an input field | `400 invalid_request`: "input: Unrecognized key: "colour"" |
| A value outside `values` | `400 invalid_input`: "`resolution` must be one of: 480p, 720p, 1080p." |
| A `duration` outside `min` and `max` | `400 invalid_input`: "`duration` must be between 4 and 30." |
| Too many images | `400 invalid_input`: "This model takes at most 16 images." |
| A file that is not a link or data URL | `400 invalid_input`: "`images[0]` must be an https URL or a base64 data URL (data:image/png;base64,...)." |
| A missing required field | `400 invalid_input`: "`prompt` is required." |
| A combination with no price | `400 variant_unavailable`: "... Priced options: 480p, 720p, 1080p." |

## Length from a file

Some models take their length from an input: lip sync, speech to video, video upscales, video edits and motion control. Their catalogue entry lists `duration_must_cover` (for example `["video", "audio"]`). You still send `duration`, and the generation is priced on it. It must be at least as long as the file, in whole seconds rounded up.

- A file longer than `duration` fails the generation with `invalid_input`. The message says the `duration` to send. Nothing is charged.
- A file longer than the model's `max` fails with `invalid_input`, and the message says how long the model takes.
- A clip that measures 5.02 seconds counts as 5: up to a tenth of a second over is forgiven.

## Examples by kind

Each example is a request body for `POST /v1/generations`. Read the model's `params` first: options differ from model to model.

### Text to video

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-text-to-video-$(uuidgen)" \
  -d '{ "model": "seedance-2.5", "input": { "prompt": "A slow push-in on a perfume bottle on wet black stone", "resolution": "720p", "duration": 5, "aspect_ratio": "9:16" } }'
```

### Image to video, and first and last frame

`images` holds the first frame; `end_image` the last, on models that list it.

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-first-last-frame-$(uuidgen)" \
  -d '{ "model": "kling-3.0", "input": { "prompt": "She smiles and lifts the cup", "images": ["https://example.com/start.jpg"], "end_image": "https://example.com/end.jpg", "resolution": "720p", "duration": 5 } }'
```

### Video with sound

`generate_audio: true` selects the `+audio` price on models that make sound.

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-video-with-sound-$(uuidgen)" \
  -d '{ "model": "kling-3.0", "input": { "prompt": "Rain on a window, a soft piano", "resolution": "720p", "duration": 5, "generate_audio": true } }'
```

### Reference video

`video` is a clip to follow. Where the model lists a `+video_input` price, it applies, and the clip's seconds are billed at that rate.

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-reference-video-$(uuidgen)" \
  -d '{ "model": "kling-4.0", "input": { "prompt": "Same camera move, a red sports car", "video": "https://example.com/reference.mp4", "resolution": "720p", "duration": 5 } }'
```

### Images: generate, several, edit

`n` is how many images; an edit sends the picture in `images`.

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-image-several-$(uuidgen)" \
  -d '{ "model": "gpt-image-2", "input": { "prompt": "A red sneaker on white", "resolution": "1k", "aspect_ratio": "1:1", "n": 2 } }'
```

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-image-edit-$(uuidgen)" \
  -d '{ "model": "gpt-image-2", "input": { "prompt": "Make the sneaker blue", "images": ["https://example.com/sneaker.jpg"], "resolution": "1k" } }'
```

### Voice-over

`text` is what to say; `quality` picks the price tier on models that have one. Priced by each started 1,000 characters.

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-voice-over-$(uuidgen)" \
  -d '{ "model": "elevenlabs-tts", "input": { "text": "Fresh coffee, delivered before you wake up.", "quality": "turbo" } }'
```

### Music

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-music-$(uuidgen)" \
  -d '{ "model": "flowmusic", "input": { "prompt": "A warm lo-fi beat with soft keys", "duration": 30 } }'
```

### Lip sync and talking avatars

These take their length from the files, so `duration` must cover them (see [Length from a file](#length-from-a-file)).

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-lip-sync-$(uuidgen)" \
  -d '{ "model": "bytedance-lipsync", "input": { "video": "https://example.com/face.mp4", "audio": "https://example.com/line.mp3", "duration": 9 } }'
```

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-avatar-$(uuidgen)" \
  -d '{ "model": "kling-avatar-pro", "input": { "images": ["https://example.com/presenter.jpg"], "audio": "https://example.com/voiceover.mp3", "duration": 12 } }'
```

### Upscale

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-upscale-video-$(uuidgen)" \
  -d '{ "model": "topaz-video-upscale", "input": { "video": "https://example.com/clip.mp4", "resolution": "1080p", "duration": 8 } }'
```

```bash cURL
curl -s -X POST https://vidlab.ai/v1/generations \
  -H "Authorization: Bearer $VIDLAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: docs-upscale-image-$(uuidgen)" \
  -d '{ "model": "topaz-image-upscale", "input": { "images": ["https://example.com/photo.jpg"], "resolution": "2k" } }'
```
