POST /v1/media/videos does not wait: it answers 202 with a media job in queued, and you read the job back until it is completed or failed. The finished clip is a file. Images are the synchronous case — see Images.
The media job object
string
med_….string
Always
media_job.string
video. Other async media kinds share the object and the routes below.string
queued → processing → completed | failed.string | null
The model rendering it.
object
The request as accepted.
object | null
On
completed: { files: [{ file_id, content_type, width, height, duration_seconds }] }. Dimensions are null where the model did not report them.object | null
On
failed: { code, message } — the reason, safe to repeat, so a refusal and an outage read differently.integer | null
What was debited, in integer micro-USD, once the job finished:
null while it runs, 0 on a failure — a job that fails is not billed.string | null
The session whose agent submitted it;
null for a job submitted through this API.string
Submission time.
string | null
When it reached a terminal status.
Generate a video
POST /v1/media/videos → 202 Accepted — scope agents:write, Idempotency-Key required.
string
required
A model id from
GET /v1/media/models?kind=video. Video models publish no price, so there is no default to pick for you.string
required
What to render.
string[]
One public
http(s) image to animate from. A private or loopback host is validation_failed.integer
Target duration, 1–60. Models honour it as they can.
string
Such as
16:9 or 9:16.integer
Repeat an earlier result.
Retrieve a job
GET /v1/media/{id} → 200 OK — scope agents:read. Poll it; a job left rendering for over thirty minutes is failed and not billed. Any med_ reads here, a clip job included — the same object GET /v1/media/clips/{id} answers.
Response
GET /v1/files/{file_id}?download=true. The file carries source.type = video_generation and source.job_id = this job.
A job an agent submitted with generate_video carries its session_id, and that session’s event stream announces it: media.job.queued, then media.job.completed or media.job.failed. A job submitted here has no session, so poll it.
List jobs
GET /v1/media → 200 OK, cursor-paginated — scope agents:read. See Pagination.
string
video (or another async kind).string
queued, processing, completed or failed.string
Jobs an agent submitted from one session.
number
Page size, 1–100.
string
The
next_cursor of the previous page.Billing
A job is billed what it actually cost, on the media tier, when it completes; nothing is quoted beforehand. At submit the organization’s prepaid balance is checked against a small floor —insufficient_credits if it is below it — and the debit settles under the job id at completion, exactly once. A job that fails, is refused, or is abandoned is not billed.