Semantic search over the org's own footage
Find MOMENTS in your library by describing what they look like. The query uses the same visual-semantic index as the footage, so it matches on visual content — "wide shot of a speaker at a whiteboard", "hands on a keyboard", "city skyline at dusk" — including shots nobody talks about (which is where transcript search fails). Results are time-ranged: feed `mediaId` + `startSec`/`endSec` straight into apply_composition as a clip. `q` is required; `limit` defaults to 10 and caps at 25. `indexing` is COVERAGE, not emptiness: it is true whenever some of the org's footage is not in the visual index yet (media that predates it, or still processing), and it can be true ALONGSIDE results — then read them as "the best moments among what we have looked at so far". Empty `results` with `indexing: true` is a state, not a failure; re-run the item through processing to index it. The first search after an idle period can take up to ~90s; subsequent searches are typically faster.
API key auth. Prefix cf_live_ for production orgs, cf_test_ for sandbox.
In: header
Query Parameters
What the moment should look like, in plain language. Describe the IMAGE, not the words spoken.
1 <= lengthMaximum moments to return. Default 10, maximum 25.
1 <= value <= 2510Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/media/search?q=string"{ "results": [ { "mediaId": "string", "name": "string", "score": 0, "startSec": 0, "endSec": 0, "thumbUrl": "string" } ], "indexing": true}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}{ "x402Version": 2, "accepts": [ {} ], "error": "string"}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}{ "error": { "code": "string", "message": "string", "contract": "string", "contractVersion": "string", "details": { "property1": null, "property2": null } }}Buy a derived fact (subject track or behind-subject matte) POST
Purchases one enhancement for this source. `matte` REQUIRES `intent:{startSec,endSec}` — the clip's SOURCE window — because a matte's cost scales with its duration. For `subjectTrack` the same `intent` is OPTIONAL: give the clip's source window to buy the track the render will look up for THAT clip (and pay only for its duration); omit it for the whole source. If the fact already exists (pending or ready) this returns it with `alreadyExisted:true` and charges nothing. Charging happens on DELIVERY, never here: a job that never lands is never billed.
Buy a behind-subject matte for one source window POST
Bakes the alpha matte that lets a graphic sit BEHIND the subject for a specific source window. The window is the clip's SOURCE trim (`startSec`/`endSec` in seconds into the underlying file), not timeline time, and it is required — a matte's cost scales with its duration. Async: poll `GET /media/{id}/facts` for the matte fact's status. If a matte for this exact window already exists (bought earlier, or baked by a compose that put a graphic behind the subject) this returns 200 with the existing state and charges NOTHING. `summary.presenceFraction` on the delivered fact is the viability signal: below 0.6 there is no reliable silhouette, and that matte is delivered free.