Ask our agent
Say what you want made, and our agent makes the whole video with you: it writes the script, makes the frames and the clips, and checks with you on the way. It asks before each paid step, unless you give it a spending cap. You can run it from the dashboard (Home, "Ask our agent") or from your code with one key.
How a run works
POST /v1/agent/runswith yourprompt. You get arun_idat once, and the run isrunning.- Read
GET /v1/agent/runs/{run_id}about every 10 seconds.messageis what the agent says now;messagesis the whole conversation. - When the agent needs you,
waiting_forsays what for:answers(statusneeds_input): readquestions[](some haveoptions) and answer them all in one reply:POST /v1/agent/runs/{run_id}/messageswith{"text": "..."}. With no questions, the agent paused: say go on withPOST /v1/agent/runs/{run_id}/approve.quote(statusneeds_approval): the next paid step costs aboutquote_usd. Say yes withPOST /v1/agent/runs/{run_id}/approve, or ask for a change with a reply.checkpoint(statusneeds_approval): a script, frames or a first clip waits incheckpoints[]. Approve it (POST /v1/agent/runs/{run_id}/approve, optionally with itscheckpoint_id), or reply with a change.
- When the run is
succeeded,output.videos[].urlholds the finished video (andoutput.images,output.audio;output.textholds a written answer, such as hooks or a script). Download it right away.
Send "approval": "auto" with max_price_usd and the agent goes on by itself while its media spend stays within that cap; anything over it waits for your yes. You can still reply or cancel while it works.
curl -s https://vidlab.ai/v1/agent/runs \
-H "Authorization: Bearer $VIDLAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: coffee-ad-1" \
-d '{"prompt": "A 20 second ad for my coffee brand: a woman in her kitchen, warm morning light", "inputs": {"images": ["https://example.com/bag.png"], "aspect_ratio": "9:16"}}'The request
| Field | Type | What it is |
|---|---|---|
prompt | string, 3 to 8,000 characters | What you want made, in plain words. Required. |
model | opus-5.5 | The agent's model. The default. |
effort | medium, high | How hard it thinks at each step. Default medium. |
approval | ask, auto | ask (the default): it asks before each paid step and at each checkpoint. auto: it goes on by itself up to max_price_usd. |
max_price_usd | number, up to 1,000 | The most the run may spend on media without asking. Required with auto. |
checkpoints | key, all, none | Where it stops for a look: key (the default: the script and the first clip), all (frames too) or none. |
media | fast, balanced, quality | How the media is made. Default balanced. |
brand_id | string | One of your brands (the app's brand id). Default: your selected brand. The agent uses what it knows about it. |
inputs | object | Your files and words: images (up to 10 https links), audio, video (one https link each), product_name, brief, script, aspect_ratio (9:16, 16:9, 1:1, 4:5). Upload a local file first (POST /v1/uploads). |
An Idempotency-Key header makes a resend find the same run for the rest of the UTC day.
Endpoints
| Method | Path | What it does |
|---|---|---|
POST | /v1/agent/runs | Starts a run. |
GET | /v1/agent/systems | What the agent can make (public, no key; see below). |
GET | /v1/agent/runs | Your runs, newest first (?limit= 1 to 100). |
GET | /v1/agent/runs/{run_id} | Reads a run. |
POST | /v1/agent/runs/{run_id}/messages | Replies to the agent: {"text": "..."}, optionally with inputs. |
POST | /v1/agent/runs/{run_id}/approve | Says yes: to the next step's price, or past a checkpoint ({"checkpoint_id": "..."} optional). |
POST | /v1/agent/runs/{run_id}/cancel | Stops the run. Safe to repeat. |
Every call needs your key. Dashboard keys have full access; a scoped key needs the runs scope.
What it can make (Systems)
GET /v1/agent/systems (no key) lists the agent's systems: id, name, description (what it makes), kind (video or image), length_seconds (min, max), the inputs it asks for (name, label, type, required, options), a thumbnail_url and a rough price_usd (min, max). available is false while the agent is not switched on yet; the list is then our formats. To make one, start a run whose prompt names it ("Make a Drama ad for ..."). The answer may be cached for 10 minutes. The dashboard shows it as Systems.
The run
| Field | What it holds |
|---|---|
status | queued, running, needs_input, needs_approval, succeeded, failed or cancelled. |
waiting_for | answers, quote, checkpoint, or null while it works. |
message, messages[] | What the agent says now, and the conversation: role (agent or member), text, at. |
questions[] | While it asks: id, question, options[]. |
quote_usd | While a paid step waits for your yes: about what it costs. |
checkpoints[] | id, kind (script, frames, clip), title, text, media[] (kind, url) and status (waiting, approved, changed). |
warnings[] | Short notes from the agent. |
output | Once succeeded: videos[].url, images[].url, audio[].url, text, media_cost_usd. |
price | agent_usd (the agent's own work so far), media_usd (the media, once finished) and held_usd (set aside while it runs). |
error | Once failed or stopped: code and message. |
next_action | What to do now, in one sentence. |
What it costs
A run is billed from your balance, the same balance as your generations:
- Each model step (an image, a clip, a voice-over) is an ordinary generation at that model's price, never above the price you approved. Each one shows in your usage logs.
- The agent's own work (its thinking and writing) is billed as it goes and shows in your usage logs as "Agent".
price.agent_usdis the total so far. - When a run starts, a small amount (50 credits) is set aside, and it is released when the run ends.
A run stops if your balance runs out (error.code api_wallet_exhausted): what it made stays on the run. A cancel stops the billing at once. A run still going after 72 hours is stopped.
Errors
| Code | HTTP | What to do |
|---|---|---|
invalid_request | 400 | Fix the field the message names. |
unknown_field | 400 | Send only the fields above. |
brand_not_found | 404 | brand_id is not one of your active brands. |
api_wallet_exhausted | 429 | Add credit, then start again. |
agent_rate_limited | 429 | Too many new runs and replies for now: wait Retry-After seconds. |
agent_run_not_found | 404 | A run is visible only to the account that started it. |
agent_run_ended | 409 | The run is over: start a new one. |
agent_run_conflict | 409 | The agent could not take that now (it is working, or nothing waits for your yes). Read the run and try again. |
agent_not_available | 404 | Our agent is not switched on yet. Run a format or a model instead. |
agent_unavailable | 503 | Our agent is not available right now. Try again later, or run a model yourself (POST /v1/generations). |