CueFrame
Api

Buy a derived fact (subject track or behind-subject matte)

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.

POST
/v1/media/{id}/facts

Authorization

AuthorizationBearer <token>

API key auth. Prefix cf_live_ for production orgs, cf_test_ for sandbox.

In: header

Path Parameters

id*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /media/:id/facts body.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/media/string/facts" \  -H "Content-Type: application/json" \  -d '{    "kind": "subjectTrack"  }'
{  "factId": "string",  "status": "pending",  "quotedUsd": 0,  "alreadyExisted": true}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}
{  "error": {    "code": "string",    "message": "string",    "details": {      "property1": null,      "property2": null    }  }}

List derived facts for a media item, with quotes for what is missing GET

The enhancement menu. `facts` is everything expensive we have already computed about this source — subject tracks, mattes — with its status, a small summary a caller can act on without fetching the artifact, and `charge` (what it was billed; absent when it cost nothing, e.g. a matte produced as a side effect of a compose you already paid for, or one delivered below the behind-subject presence floor). `offers` is what is NOT present yet, with a real server quote. A matte is offered ONLY when you pass `startSec`+`endSec` — the clip's SOURCE window — because a matte's price is a function of its duration and a whole-source quote for a three-second clip is not a price. Pass the window from the editor and you get a per-clip matte quote plus the status of that window's matte; omit it from the library and you get everything except the matte.

Semantic search over the org's own footage GET

Find MOMENTS in your library by describing what they look like. The query is embedded with the same CLIP model that embedded every indexed frame, 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. TIMING: the text encoder scales to zero, so the first search after an idle period can take up to ~90s while it cold-starts — that is a documented wait, not a hang; subsequent searches are fast.