202 with a media_job you poll (or receive by webhook). When it completes, every clip is a published file in your library, scored for virality by the same pipeline the clip_video tool uses in a session.
The media job object
string
Unique id (e.g.
med_01H...).string
Always
media_job.string
Always
clip here.string
queued → processing → completed | failed.string | null
Always
null for clipping; the pipeline is not model-selectable.object
The request as accepted, defaults filled in. Fields you did not send are
null.object | null
{ clips: [...] } once completed, otherwise null. Each clip: file_id, title, start_seconds, end_seconds, duration_seconds, and virality — total, shareability, hook_strength, story_quality, emotional_impact, each an integer 0–100.object | null
{ code, message } once failed, otherwise null.integer | null
What the job actually cost, settled on completion.
null until then and for a failed job — a failure is not billed.string | null
Always
null for a job submitted here; set when the clip_video tool queued it.string
Submission timestamp.
string | null
When the job reached a terminal status.
Submit a clipping job
POST /v1/media/clips — scope agents:write. An Idempotency-Key header is required — a submit without one is refused with validation_failed — so a retried submit replays the job instead of queueing (and billing) a second one; the same key with a different body is idempotency_conflict.
string
required
A public
http(s) URL of the source video. Private, loopback and link-local hosts are refused with validation_failed.string
default:"9:16"
9:16 (reframed to the speaker) or 16:9 (kept as shot).boolean
default:"false"
Tighten pauses inside each clip.
string
default:"none"
none, clean, bold or karaoke. none burns no captions.string
BCP-47 hint for transcription (e.g.
de, pt-BR). Omit to detect.integer
default:"15"
Shortest clip to keep, 5–180.
integer
default:"60"
Longest clip to keep, 5–180; must not be below
min_seconds.string
A title for clips the scorer does not name itself.
402 insufficient_credits when the organization’s prepaid balance is empty. There is no per-tenant concurrency cap on this route — your balance bounds you, not a turn — unlike the clip_video tool, which keeps one active job per session.
Retrieve a job
GET /v1/media/clips/{id} — scope agents:read
status: "failed", result: null, cost_micro_usd: null and error: { "code": "provider_error", "message": "..." }.
List jobs
GET /v1/media/clips — scope agents:read
string
queued, processing, completed or failed.number
Page size, 1–100.
string
The
next_cursor of the previous page.clip_video tool cuts inside a session reach that session as files, not as jobs here.
Webhooks
Subscribe an endpoint tomedia.job.queued, media.job.completed (data.file_ids names the clips) or media.job.failed (data.code) to be told rather than poll. Every envelope carries data.job_id and data.kind: "clip".
Pricing
A job is billed what it actually cost — input minutes, transcript words, scoring tokens, cut clips — once it finishes, andcost_micro_usd is that figure. See Pricing.