Model list
Every model, its options and its prices, as JSON. GET /v1/models needs no key. The price you see is the price you pay: VidLab picks the route, you never pay more than the listed price.
curl -s "https://vidlab.ai/v1/models?kind=video"import requests
models = requests.get("https://vidlab.ai/v1/models", params={"kind": "video"}).json()["data"]
for m in models:
print(m["id"], m["unit"], m["prices"])const res = await fetch("https://vidlab.ai/v1/models?kind=video");
const { data: models } = await res.json();
for (const m of models) console.log(m.id, m.unit, m.prices);| Query | Values | What it does |
|---|---|---|
kind | video, image, audio, lipsync, upscale | Only models of that kind. |
maker | A maker's name, any case | Only that maker's models, for example maker=Google. |
search | Words | Only models whose id, name, maker or description has every word. q works the same. |
The answer is { "object": "list", "data": [ ...models ] }. GET /v1/models/{id} returns one model as { "data": model }, or 404 model_not_found. The list is public data: answers may be cached for up to 60 seconds.
The model object
{
"id": "seedance-2.5",
"name": "Seedance 2.5",
"maker": "ByteDance",
"kind": "video",
"unit": "per_second",
"description": "Generates video from text, an image, references",
"prices": {
"480p": 0.088,
"720p": 0.21,
"1080p": 0.52
},
"params": {
"resolution": { "values": ["480p", "720p", "1080p"] },
"prompt": { "required": true },
"images": { "max": 16 },
"negative_prompt": {},
"seed": {},
"duration": { "min": 4, "max": 30 },
"aspect_ratio": { "values": ["16:9", "9:16", "1:1"] }
},
"featured": true,
"save_pct": 34,
"routes": 2,
"status": "operational"
}| Field | Type | What it is |
|---|---|---|
id | string | The id you send as model. |
name, maker | string | Display name and the company that made the model. |
kind | string | video, image, audio, lipsync or upscale. |
unit | string | What one unit of the price is (see Units). |
description | string | Optional. A one-line summary. |
prices | object | USD per unit for each priced option (see Variants). |
params | object | The input fields this model takes (see The params object). |
media | object | Optional. Example still and video paths. |
featured | boolean | Shown first on the models page. |
save_pct | number | Optional. How much cheaper we are, in percent, at the setting the price starts from (our cheapest one), rounded down. |
offer | object | Optional. The price a model card leads with: variant (our cheapest plain option), price_usd, market_usd (the usual price for the same unit, shown struck through) and pct (the saving, rounded down). Only models we are cheaper on have one. |
duration_must_cover | array | Optional. For models whose length comes from an input file: which files (video, audio) duration must cover. |
routes | number | How many routes can run this model right now. |
status | string | operational, degraded or down. |
Units
| Unit | One unit is | Counted from |
|---|---|---|
per_second | one second of output | duration |
per_image | one image | n (default 1) |
per_job | one call | always 1 |
per_1k_chars | each started 1,000 characters | text (or prompt) |
per_minute | each started minute | duration in seconds |
The price of a call is the variant's price times the units. A 5 second clip at 720p on a model priced 0.21 per second costs 1.05. The wallet moves whole cents, so a price is rounded up to the next cent: the quote, the reservation and the charge are all that same number.
Variants
A model's prices are keyed by variant. A variant is the resolution or quality, then flags joined with +:
+audiowhen the call asks for sound (generate_audio: true),+video_inputwhen the call sends a referencevideo,*when the model has one price for everything.
VidLab picks the variant from your input: the exact key first, then the key with fewer flags, then the bare resolution or quality, then *. Options you leave out get the model's first allowed value, so the quote and the run always agree. If no priced variant matches, the call answers 400 variant_unavailable with the priced options in the message.
The params object
params lists every input field the model accepts. A field that is not listed is refused, never ignored. Each entry has up to three keys:
| Key | Meaning |
|---|---|
required | The field must be sent. |
values | The only allowed values. Matching ignores letter case. |
min, max | Number limits. For images, the most images; for n, how many images per call; for duration, seconds. |
{}means the field is accepted with no limit beyond Input fields.- A list of lengths (
"duration": { "values": [4, 6, 8] }) means only those lengths run. paramsonly lists what the model can really do: an option that no route can carry is not listed. A referencevideoorgenerate_audiois listed only while its price (+video_input,+audio) is.
Model status
GET /v1/status lists every model with its status and routes count. No key needed.
{ "object": "list", "data": [{ "model": "seedance-2.5", "status": "operational", "routes": 2 }] }A model that is down can still be called: the generation is accepted and fails with model_busy if no route can take it, at no charge.
UGC Real 1
ugc-real-1 is VidLab's own image model, made for realistic phone-shot UGC people: the kind of picture a creator would take on a phone. It costs one flat price per image, shown on its model page next to real examples of what it makes.
It takes words only. Send prompt (up to 2,000 characters) and, if you want another shape, aspect_ratio (9:16 by default). Short prompts are fine: the model writes your words out into a detailed photo description before it draws. A call makes one image. It takes no pictures, no n, no resolution and no seed: a field it does not list is refused with 400 invalid_input before anything is held.
curl -s -X POST https://vidlab.ai/v1/generations \
-H "Authorization: Bearer $VIDLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"model":"ugc-real-1","input":{"prompt":"a woman in her kitchen, talking to the camera"}}'Poll the generation as for any other model. A finished call has one picture in outputs, and a failed or blocked one is not charged.