# Docs - [One video project for people and agents](/docs): A shared video-composition substrate: edit locally in the desktop app or author the same project through MCP, REST, CLI, and x402. - [Templates](/docs/templates): One document per finished film, with its inputs, looks and brand kits, applied to your footage from the desktop, an agent, the CLI or the API. - [Setup](/docs/setup): Point your agent at CueFrame — over MCP, the CLI, or the REST API — and sign in once. - [Quickstart](/docs/quickstart): Intent to rendered video in three steps over MCP. - [Pay per call](/docs/pay-per-call): The keyless, pay-per-call way for agents to use CueFrame — over MCP (recommended) or REST. No account, no API key. - [Public roadmap](/docs/roadmap): The public priorities for CueFrame's shared human-and-agent video editing substrate. - Api - **Media** - [Analyze a timeline transcript for edit decisions](/docs/api/analyzeTimeline): Returns filler, silence-gap, and emphasis word indices for an editor timeline. Analysis settings are selected server-side and cannot be overridden. - [Analyse a media item's transcript](/docs/api/analyzeTranscript): Ask ONE editorial question of a transcript and get the answer as text: `summary` (what is actually said, plus the takeaways), `chapters` (where the subject changes), or `highlights` (the moments that stand alone as a short). PRECISION: timestamps are ABSOLUTE seconds from the start of the media and every one is verified against the transcript before you see it (a fabricated timestamp fails the call rather than shipping) — but they are LINE-START markers roughly 15s apart, so a boundary can sit up to 15s BEFORE the moment you asked for. Treat every span as APPROXIMATE: use it to LOCATE the moment, then refine the in/out against the word timings from GET /v1/media/{id}/context before you cut. Feeding a raw span straight into a clip trim will start it mid-sentence. Pass `window` to analyse one slice; omit it for the whole thing. This is a METERED LLM call, not a read: it bills on measured token spend, and a recording too long to analyse in one pass is rejected with 422 `transcript_too_long` (over ~100k characters, roughly two hours of speech) rather than silently summarising only its first half — narrow it with `window`. 422 `media_no_transcript` means the item has no speech on file (or none inside your window); GET /v1/media/{id}/context shows transcript state, and GET /v1/media/{id}/transcript returns the raw words. - [Request cancellation of a hosted processing run](/docs/api/cancelHostedProcessingRun): Ask a hosted processing run to stop, and get back its status plus whether a remote stop was requested. A request is not proof the work stopped, so poll the run afterward; a finished run is returned unchanged. - [Initiate a direct upload (presigned PUT URL)](/docs/api/createMediaUpload): Reserve a media id and get a presigned URL for uploading a local video, audio, or image file of up to 5 GiB. PUT the raw bytes to that URL, then call POST /v1/media/{id}/finalize to start processing. - [Mint a short-lived token for the signed upload lane](/docs/api/createUploadToken): Get a token for the signed resumable upload lane used by browser and desktop uploaders, valid for about 30 minutes and optionally scoped to one project. API clients should use POST /v1/media for a presigned PUT instead. - [Delete a media item](/docs/api/deleteMedia): Delete a media item that is no longer needed. Refused with media_in_use, naming the projects and sessions involved, while anything still references it, so remove those references first. - [Finalize a direct upload (trigger processing after the bytes are PUT)](/docs/api/finalizeMedia): Confirm the bytes reached the presigned URL and start processing, the step after POST /v1/media. Audio and video move to processing while images complete at once; optionally declare an audio role of vo, music, sfx, or ambience. - [Generate media with AI (video, image, or audio)](/docs/api/generateMedia): Generate a new media item from a text prompt: text-to-video, text-to-image, image-to-video, speech, music, or sound effects (generator 'auto' selects the supported model). Async — returns a media id that flips to ready when generation finishes; poll GET /media/:id or register a media.completed webhook. Priced on what the model actually costs; refused with 402 if your balance cannot cover the quote (see GET /me). - [Get one committed hosted processing artifact](/docs/api/getHostedProcessingArtifact): Get download URLs for a run's committed audio or matte artifact on the current source. The URLs last five minutes, so call it right before downloading; it returns 404 until the artifact is committed. - [Read a scoped hosted processing run](/docs/api/getHostedProcessingRun): Check a hosted processing run's overall status, dispatch state, and each operation's attempt and artifact commit. Poll it after starting a run to learn when its artifacts can be downloaded. - [Get a media item by id](/docs/api/getMedia): Read one media item's status, processing progress, duration, dimensions, frame rate, and thumbnail URL. Poll it after an upload, import, or generation to learn when the video, audio, or image is ready to use. - [Get authoring context for a media item (faces + transcript + beat/word grids)](/docs/api/getMediaContext): The read-only context an agent needs to author a composition over this source: the detected face/subject roster (face-0 = primary speaker, with normalized bbox + active-speaker share), the transcript, the temporal grids — `beatGrid` (a MUSIC bed's rhythm: bpm, beatTimesMs in milliseconds, confidence, method) and `wordGrid` (VO word-onset timings in milliseconds, from the transcript) — and a presigned `thumbnail` (~the footage at a glance). For stills at CHOSEN timestamps, call preview_frame with a one-clip composition over this media. Call this before authoring crop intents (reframe) and overlay/caption timing. The transcript and wordGrid cover one utterance page (default 20); pass transcript.data.pagination.nextCursor as after for later words. Faces are lazily detected — `faces.status` is `not_detected` until a compose/detect pass has run over the source, never a faked empty roster. `beatGrid` is null until beat analysis has run: generated music beds are analyzed automatically at delivery; an uploaded/imported bed may not carry a grid yet (on-demand analysis is not client-triggerable today). `audioRole` is the DECLARED role of an audio asset (vo | music | sfx | ambience) — author the clip source's `audioRole` from it; `envelope` carries the coarse `envelopeClass` (transient | sweep | ambient) plus any probed attack/centroid/volume stats. Both are null for footage/images or an undeclared audio asset. - [Get a presigned URL for stored media source bytes](/docs/api/getMediaDownloadUrl): Issue a presigned GET URL for the published source file CueFrame composes from. It works without an Authorization header for about an hour; read again for a fresh URL. Available once upload or import bytes are stored, before processing finishes. Required permission: media:read. - [Get a media transcript (paginated)](/docs/api/getMediaTranscript): Fetch a processed video or audio item's transcript as full text and utterances, whole by default or paged with limit, after, and before. Call it to find quotes and moments for clips or captions; 404 means no transcript exists yet. - [Import media from a URL (server-side fetch)](/docs/api/importMedia): Import media into the project from a public https URL — the server fetches and mirrors the bytes (SSRF-filtered), then processes video and audio. Async: returns a media id that flips to ready when the mirror and processing finish; poll GET /media/:id or use a media.completed webhook. - [List media items](/docs/api/listMedia): Paginated library list. Filter with ?kind= (video|audio|image|gif|asset|source|stock), ?source= (upload|generated|import-url|stock), ?tag= (exact tag) so a real library isn't an undifferentiated soup. - [List derived facts for a media item, with quotes for what is missing](/docs/api/listMediaFacts): 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. - [Buy a derived fact (subject track or behind-subject matte)](/docs/api/purchaseMediaFact): 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. - [Semantic search over the org's own footage](/docs/api/searchLibrary): 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` reports missing chunks observed in a bounded membership window; false does not prove complete coverage. Inspect `coverage` for scope and limits. Empty results mean retrieval returned no hits, not that no suitable footage exists. Optional repeated `mediaId` parameters restrict retrieval before top-k truncation (maximum 32). - [Start a direct hosted processing run](/docs/api/startHostedProcessingRun): Process a stored media source under a caller-chosen runId, optionally setting a transcription language. Async: returns 202 with dispatch state, then poll GET /v1/media/{id}/processing-runs/{runId}; one run can be active per media item. - [Buy a behind-subject matte for one source window](/docs/api/triggerMatteBake): 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. - [Trigger standalone subject/face detection](/docs/api/triggerSubjectDetection): Track faces or people across a video so renders can use the subject track. Async: returns 202 with a fact id and quote, then poll GET /v1/media/{id}/facts; a detection already pending or ready is returned free of charge. - **Clips** - [Build and persist a composition from a clip suggestion](/docs/api/composeFromSuggestion): Builds a composition from the suggestion and saves it as the active one. When the project already has a composition, send `If-Match` with its ETag (409 stale_etag on mismatch, 428 precondition_required without it). - [List clip suggestions for a media item](/docs/api/listMediaSuggestions): Read the ranked short-form clip suggestions for a video along with the analysis status, filtered by platform, format, or topic if needed. Poll it after POST /v1/media/{id}/suggestions until the status is completed. - [Reset clip suggestions for a media item](/docs/api/resetMediaSuggestions): Delete all clip suggestions for a media item, cancel any analysis still in flight, and return the count removed. Call it before analyzing again, because a media item with finished suggestions refuses a new run. - [Trigger clip-suggestion analysis](/docs/api/suggestBriefs): Analyze a video for its best short-form moments — returns ranked clip suggestions with trims, hooks, titles, captions, hashtags, and platform fit for turning long footage into shorts. Async: returns 202; poll GET /media/:id/suggestions for the ranked results. - **Projects** - [Create a project](/docs/api/createProject): Create a video project — the container for a composition (the editable timeline), its media, brand kit, and renders. Every other authoring call (import or generate media, apply composition ops, compose, render, export) takes this project's id. Set the output format here (aspectRatio, fps, resolution). - [Delete a project](/docs/api/deleteProject): Remove a video project that is no longer needed. Refused with 409 while renders are in flight, so cancel those first. Members need the owner or admin role; an x402 wallet can delete its own projects. - [Get a project by id](/docs/api/getProject): Read one video project's name, output format, brand kit, active composition summary, and latest render. Call it to check settings or fetch the last render's output URL before editing or rendering again. - [One-call agent context: composition + media + transcript + brand](/docs/api/getProjectContext): Everything an authoring agent needs to open a project, in ONE read: the active composition (with its format and markers hoisted), the project's media pool with a `hasTranscript` flag per item, the first transcribed item's word-timed transcript, and the brand kit bound to the project. Replaces the get_composition + get_media_context + get_profile opening sequence. A freshly created project reads back with `composition: null` — that is the empty state, not an error; 404 means the project doesn't exist for your org. Transcript BODIES are never inlined per media item — read another item's with GET /v1/media/{id}/transcript, and its faces/beat/word grids with GET /v1/media/{id}/context. The media pool is capped at 50; mediaPagination reports whether more exists. Continue with paginated GET /v1/media?projectId=... (list_media in MCP) to see the rest. - [List projects](/docs/api/listProjects): Page through the video projects this account owns to find the id that composition, media, render, and compose calls need. Call it when resuming earlier work instead of creating a new project. - [Update a project](/docs/api/patchProject): Change a project's name, description, output format (aspect ratio, fps, resolution), or attached brand kit. Send at least one field; call it before rendering when the video needs a different format or brand. - **Renders** - [Cancel a render](/docs/api/cancelRender): Stop a queued or running render job and get back its updated state. Call it when a render is no longer wanted; a render that already finished is refused, and a 503 means the cancel did not reach the worker, so retry. - [Create a render job](/docs/api/createRender): Render the project's composition to a finished MP4. Async: returns a render id; poll GET /projects/:id/renders/:renderId or stream progress over SSE, then download the signed output URL once status is complete. - [Get a render job](/docs/api/getRender): Check a render job's status and progress, and get its video output URL once complete, or the error and error code if it failed. Poll it after starting a render to know when the video is ready to download. - [List renders for a project](/docs/api/listProjectRenders): Page through a project's render jobs, optionally filtered by status such as error or cancelled. Call it to find a finished video, review failures, or recover a render id. - [Render a scoped motion preview of the composition](/docs/api/previewClip): A cheap, watchable MP4 of ONLY [fromSec, toSec) of the composition at preview quality (capped resolution, lighter encode). The way to judge motion — a cut, a transition, a component's animation — with real fidelity BEFORE paying for a full render. Async: returns a render job; wait_job(kind='render') or webhook render.completed for the URL. Meters the capture feature, never an exports credit. - [Refresh a render's output URL](/docs/api/refreshRenderUrl): Issue a new download URL for a complete render whose outputUrl has expired, and return it with its expiry. Call it instead of rendering the video again; it fails for renders that are not complete. - [Re-render against an existing renderJob's snapshot](/docs/api/retryRender): Queue a NEW render of an existing render's composition snapshot. Priced and billed like the render it repeats: measured output-minutes x resolution, charged when the retry completes. - [Stream render status (SSE)](/docs/api/streamRender): Server-Sent Events stream emitting `progress`, `complete`, and `error` frames until the render reaches a terminal state. Required scope: renders:read - **Sessions** - [Cancel one mux attempt while retaining the session](/docs/api/cancelMuxJob): Stop the named audio-onto-video mux attempt and keep the session so the job can be retried. Send its jobId; a job that is no longer current returns 409. - [Create a session](/docs/api/createSession): Group existing media into a named session by role, with one 'audio' file and any other role treated as video. This is the step before POST /v1/sessions/{id}/mux-job, which merges the audio onto each video. - [Delete a session](/docs/api/deleteSession): Delete a session, first cancelling any mux still running for it. Refused while a project composition references the session, so remove those references first; call it when the grouping is no longer needed. - [Poll mux job status](/docs/api/getMuxJob): Check an audio-onto-video mux job's status, timing, and error, and get the media ids of the muxed videos as they publish. Poll it after POST /v1/sessions/{id}/mux-job; 404 means no mux has started. - [Get a session](/docs/api/getSession): Read a session's files, roles, and mux state, including the media ids of any muxed outputs. Call it to confirm file roles before starting a mux or to see what a finished one produced. - [List sessions](/docs/api/listSessions): Page through this account's sessions, each a named set of media files with its mux status. Call it to find a session id for checking or retrying an audio-onto-video job. - [Trigger mux-audio-onto-video workflow](/docs/api/triggerMuxJob): Merge a session's 'audio' file onto each of its video files, using one signed alignment offset per video. Async: returns 202 with a job id, then poll GET /v1/sessions/{id}/mux-job; pass retryOf to retry a failed or cancelled job. - **Components** - [Author (create) a component](/docs/api/createComponent): Add a custom motion-graphics component to this account's library from native source, ready to place in compositions. Start from GET /v1/components/blank-source; an id that already exists returns 409, so update it with PUT. - [The blank native component source](/docs/api/getBlankComponentSource): The blank native (version 4) component source every new component starts from. Rename it by setting componentId and the template root's data-composition-id together, then create it with create_component. - [Get a component entry](/docs/api/getComponent): Read a component's metadata and prop schema, whether it is installed in this account or built in. Call it before placing a graphic on the timeline to see which inputs it accepts. - [Get a component's source](/docs/api/getComponentSource): Read an installed component's source and input schema, or an exact version with sourceVersionId. Built-in sources need builtinCollection plus sourceVersionId; call it before forking or editing a graphic. - [List component catalog (defaults + installed)](/docs/api/listCatalog): Discover the one built-in primitive (heroText, the behind-subject overlay) plus your installed components; pass projection=component-library for the maintained builtin presets and recipes. Narrow with facet filters (category, kind, tier, useCase, mood) or free-text (q / intent); when ANY filter is set, results are ordered recommended-tier-first. With NO `limit` the WHOLE (filtered) catalog returns in one page — pass `limit` only to page. Each entry carries a `placement` hint telling you exactly how to author it on the timeline. - [Patch an authored component](/docs/api/patchComponent): RFC 7396 merge patch: send only the fields you are changing. Every field you omit keeps the value it already had. Identical in effect to PUT, which merges the same way. Every placed clip renders the exact version it pins. Send `projectId`, `compositionId` and caller-observed `concurrency` to move that composition's placements to the new version in the same write; `repinned` reports them. Other placements keep rendering the previous version, and `placementsPinnedToPrevious` counts them across the org. For a single placement, update the library without projectId, then use apply_composition clip.update to install that exact immutable source pin on the chosen clip under observed dependency guards. Atomic all-use repin requires exact revision admission; unsupported guarded mode and no matching placements refuse the whole write. - [Move retired component clips to their native successors](/docs/api/repinComponent): Move clips stored in a retired form to their native (version 4) successors: a clip pinning a retired curated TSX (version 3) component, or one stored before execution pins (needsUpgrade kind unpinned-component), moves to the successorSourceVersionId the read or a refusal of such a clip names. Name clip_ids, or omit them to move every clip that has a successor. Every saved input is kept. Clips with no successor are listed in withoutSuccessor, and clips whose stored inputs the successor refuses in inputsRefused; a write never leaves a retired clip in place, so rebuild or remove those in the same edit that upgrades the others. - [Resolve an exact builtin library artifact](/docs/api/resolveBuiltinComponent): Fetch the exact saved version of a builtin library item by collection, id, and 64-character revision hash. Call it with an identity from the component library to pin a graphic or template's source before using it. - [Update an authored component](/docs/api/updateComponent): Every placed clip renders the exact version it pins. Send `projectId`, `compositionId` and caller-observed `concurrency` to move that composition's placements to the new version in the same write; `repinned` reports them. Other placements keep rendering the previous version, and `placementsPinnedToPrevious` counts them across the org. For a single placement, update the library without projectId, then use apply_composition clip.update to install that exact immutable source pin on the chosen clip under observed dependency guards. Atomic all-use repin requires exact revision admission; unsupported guarded mode and no matching placements refuse the whole write. - **Brand Kits** - [Create (or upsert) a brand kit](/docs/api/createBrandKit): Create or upsert a brand kit. Gated on the `brand_kits` boolean entitlement, which the FREE plan grants — brand-first authoring is deliberately never paywalled — so this is available to every account and costs no credits. A plan without it returns 402 billing_required (`details.featureId: "brand_kits"`). Discover the gate WITHOUT a failed round-trip via GET /v1/me — its `entitlements.brand_kits.included` tells you up front. - [Reserve presigned PUT slots for inspiration exemplar frames](/docs/api/createExemplarUploads): Returns presigned PUT URLs under this org's `brand-inspiration/…` prefix — the only namespace the brand-kit upsert accepts `exemplarKeys` from. PUT each curated reference frame (≤720px jpeg recommended — the frames become vision input downstream), then upsert the kit with the returned keys. This is the ingest door for agent-driven kit extraction (the `extracting-brand-kits` skill on GET /skills). - [Extract brand tokens from a website URL](/docs/api/extractBrandKit): Queue brand-token extraction from a website URL — ASYNC: returns a 202 job receipt; poll GET /v1/jobs/{jobId} (or MCP wait_job kind=brand_kit_extract) for the tokens (colors, fonts, title, description) on the succeeded result. The service inspects the site under a 20-second limit and does NOT persist a kit (pass the result to POST /brand-kits). A blocked (private-network), non-2xx, non-HTML, or slow URL degrades to EMPTY token arrays on a SUCCEEDED terminal rather than erroring; succeeded extractions are reused for 5 minutes per URL. - [Get a brand kit by id](/docs/api/getBrandKit): Read one brand kit's name, tagline, colors, fonts, and voice guidelines. Call it to match on-brand copy and graphics when authoring a composition, or to confirm what a brandKitId holds. - [Presign a brand kit's inspiration exemplar frames](/docs/api/getBrandKitExemplars): Returns short-lived URLs for the kit's exemplar frames (the pixels the maker and judge condition on). Filter to one motif's evidence frames with `motifId`. Vision-budget-bounded consumers should keep `limit` small (default 6). - [List brand kits (read-only)](/docs/api/listBrandKits): Page through the account's brand kits, each with its colors, fonts, and voice guidelines. Call it to find a brandKitId before attaching a brand to a project or rendering a template on brand. - **Webhooks** - [Register a webhook endpoint](/docs/api/createWebhook): Register a webhook so long-running jobs (render/compose/media) notify you instead of blocking on wait_job. Body: `url` (https, must pass SSRF checks) + `events` (see the WebhookEvent enum). DELIVERY: each event is a POST with body `{ event, timestamp, projectId?, data }` and Standard-Webhooks headers `webhook-id`, `webhook-timestamp`, `webhook-signature: v1,` (+ `x-cueframe-event`). The `secret` (`whsec_`) is returned ONCE here — verify the raw body with `new Webhook(secret).verify(rawBody, headers)`. ACTIVATION (synchronous, no separate step): on create, CueFrame POSTs a signed `webhook.verify` challenge; your endpoint must reply 2xx echoing `data.token` (raw body === token, or JSON `{token}`/`{challenge}`). On success the response is `status:"active"`; otherwise `status:"pending"` with `verification.reason` and the webhook receives NO events until it verifies (recover with POST /webhooks/:id/verify — no delete/recreate). Full contract + per-event `data` shapes: GET /webhooks/events. - [Delete a webhook endpoint](/docs/api/deleteWebhook): Remove a webhook endpoint so it stops being used for event deliveries. Call it when an integration is retired or its callback URL is gone; returns 204 with no body. - [Get a webhook endpoint](/docs/api/getWebhook): Read one webhook endpoint's URL, subscribed events, settle delay, and enabled state. Call it to debug missing deliveries or to confirm which events a callback URL receives. - [Get the webhook delivery contract](/docs/api/getWebhookEvents): The machine-readable webhook contract: the delivery envelope, Standard-Webhooks signing (secret format, signed content, how to verify), the synchronous echo-the-token ownership handshake, and every subscribable event with its exact `data` fields. Read this before building a receiver — it answers 'what's the payload shape / how do I verify the signature / how does activation work' without guessing. - [List webhook endpoints](/docs/api/listWebhooks): Page through the webhook endpoints registered on this account, with their URLs, subscribed events, and enabled state. Call it to see what already receives render, media, and compose events before adding another. - [Update a webhook endpoint](/docs/api/patchWebhook): Change a webhook endpoint's URL, events, settle delay, or enabled flag. A new URL goes back to pending and re-runs the ownership challenge; an unverified endpoint cannot be enabled here, so use POST /v1/webhooks/{id}/verify. - [Fire a webhook.test delivery](/docs/api/testWebhook): Queue a webhook.test delivery to a registered endpoint to check your receiver before relying on render or media events. Returns a delivery id; limited to 5 per minute per key and 100 per day per endpoint. - [Re-run webhook ownership verification](/docs/api/verifyWebhook): Re-send the signed `webhook.verify` ownership challenge to a PENDING webhook's url and, if the endpoint now echoes `data.token` in a 2xx, flip it active — IN PLACE (id + secret preserved; no delete/recreate). Use it to recover after fixing a receiver that failed the challenge at create time. An already-verified webhook returns `status:"active"` unchanged (idempotent). Returns the same `{ status, verification? }` shape as create. - **Health** - [OpenAPI 3.1 document for the v1 API](/docs/api/getOpenAPISpec): Returns the generated OpenAPI 3.1 document. Unauthenticated so SDK tooling (Orval, Postman, redocly) can fetch without a key. Cacheable for 5 minutes. - [Shallow + deep health check](/docs/api/health): Shallow (default) returns 200 with a minimal liveness payload for load balancers. Append `?deep=1` to exercise component bindings (rate-limiter). Unauthenticated. - [Return the caller identity + permissions](/docs/api/whoami): Echoes the `orgId`, `permissions`, and key metadata derived from the Authorization header (or x402 payment). Useful for SDKs to confirm which org a key is bound to and what permissions it carries. - **Skills** - [Get a skill's SKILL.md (markdown)](/docs/api/getSkill): Returns the raw SKILL.md for the named skill as `text/markdown`, ready to load into an agent. 404 if the skill name is unknown. Unauthenticated. - [List available CueFrame agent skills](/docs/api/listSkills): Returns the agent skills CueFrame publishes (e.g. `cueframe-cli`). Metadata only — fetch the markdown body from GET /skills/{name}. Unauthenticated, like /openapi.json. - **Compose Session** - [Close a compose session](/docs/api/closeComposeSession): End a compose session and discard its uncommitted scratch composition when the work is finished or abandoned. Scratch also closes on its idle timeout; commit first if the edits should be kept. - [Commit the session scratch onto the project's active composition](/docs/api/commitComposeSession): Save a compose session's scratch edits as the project's active composition and return the new ETag. Call it once previews look right; the scratch is then removed from the session. Refused with 409 if the active composition changed after the session started. - [Read the session's scratch composition](/docs/api/getComposeSessionComposition): Pure read: returns the composition currently held in the session's SCRATCH (what the author LLM has been editing over this session), NOT the project's active composition. The Director ensemble reads this back per candidate and returns it as the authored composition — the winner is saved downstream, so a candidate never commits its scratch to active. 404 when the session is unknown/foreign or has never written a scratch. - [Open an isolated scratch composition](/docs/api/openComposeSession): Mint isolated scratch state for project authoring. This returns immediately and starts no sandbox or render provider; use /preview-frame-jobs and /score-composition for durable preview and verification work. The scratch closes automatically after its idle TTL or explicitly via DELETE. Optionally seed it from a supplied composition (seedComposition); a bodyless open derives from the project's active composition. - **Workspace** - [Mint a workspace (project + imported source) in one call](/docs/api/createWorkspace): The one-call editing handle: create a project and import the source video URL into it. Returns { projectId, mediaId } — the handle a (paying or keyed) agent threads through the compose/render loop. The import is async; poll GET /v1/media/:mediaId for readiness. - **Account** - [Remember a style preference](/docs/api/createTasteEntry): Saves one durable style preference for the org, with its source. Identical text is a no-op. Refused (never truncated) past the per-entry or per-org limit, and while the owner has learned taste off. - [Forget a style preference](/docs/api/deleteTasteEntry): Remove one saved style preference from this org's learned taste. Call it when a preference is wrong or outdated; get the tasteId from GET /v1/profile/taste. - [Return the caller's account: identity, plan, entitlements, cost ceilings](/docs/api/getAccount): Returns the org this key is bound to (server-resolved from auth, never the body), the current plan, a per-feature `entitlements` map, and `costCeilings` (e.g. the generate_media per-call USD ceiling). Read it BEFORE a metered call (create_render / compose / generate_media / create_brand_kit) to budget without burning a round-trip on a 402. READ `balance`, NOT `included`: most capabilities are credit-funded — rendering, generation, previews, the judge and the Director carry no separate per-plan allowance and instead spend the shared wallet named in `fundedBy`, so each `balance` is that one wallet restated in the feature's own `unit`. Generation is also bounded by the disclosed generationLimit for accounts that have not purchased credits; `included:false` means the plan genuinely lacks the feature. Plan/entitlement values come from the billing backend best-effort; unknown values are `null` and `billingConfigured:false` flags an environment where billing isn't configured. - [Read the org's Profile — its legible taste](/docs/api/getProfile): One read for everything the platform knows about this org's taste: brand kits, registered critics (the machine-checkable standard both the Director's gates and score_composition enforce), the critics' reference media with presigned thumbnails, the recent checkpoint-decision log (what was approved/revised/abandoned, where), and the learned taste: style preferences saved from earlier feedback. Read this before composing for an org you haven't worked with — it is the house style. Learned taste is advice: the current request, its brief, the project, the brand kit, exclusions and critics take precedence. - [List the org's learned taste](/docs/api/listTaste): Read the style preferences saved for this org and whether learned taste is switched on. Call it before composing to apply the org's preferences, or to find the id needed to edit or forget an entry. - [Edit a style preference](/docs/api/updateTasteEntry): Correct the text or source of a saved style preference while keeping its id. Call it when a preference has changed; get the tasteId from GET /v1/profile/taste. - [Turn learned taste on or off](/docs/api/updateTasteSettings): Owner only. Turning it off deletes every entry; nothing is saved or recalled until it is back on. - **API Keys** - [Create a scoped API key (session credential only)](/docs/api/createApiKey): Mint an API key with chosen resource permissions and an optional expiry for scripts and integrations; the secret is shown once. Requires a signed-in session, so API keys are refused with 403. - **Billing** - [Start a hosted Stripe checkout for a plan/interval](/docs/api/createCheckout): Body `{ plan, interval }` → returns a hosted Stripe checkout `url` to open in a browser to complete payment. Upgrades the CURRENT org (server-resolved from your key/identity, NEVER the body). Always a hosted URL — an existing saved card is NEVER charged without the human confirming on Stripe. `interval:"year"` selects the annual plan. Discover valid combos with GET /v1/billing/plans. Requires `billing:write`. - [List the plan catalog: tiers, intervals, product ids, prices](/docs/api/getBillingPlans): Returns every purchasable {tier, interval} and its billing catalog product id — discovery to read BEFORE POST /v1/billing/checkout so an agent requests a real plan/interval instead of guessing. `priceUsd` is best-effort (null if unavailable); `billingConfigured:false` flags an env without billing. - [List metered usage events (the A2 usage ledger)](/docs/api/getUsage): Every metered billing event, newest-first, with attribution: featureId, amount, the project/job that produced it, and the event's LIST price in USD (the invoice may zero it inside a plan allowance). Filter by projectId, jobId, and/or a [from, to) epoch-ms period. Events appear moments after the job's success terminal (the meter is scheduler-dispatched). - **Briefs** - [Create a brief (the persisted intent the Director composes from)](/docs/api/createBrief): Persist the video's intent — goal/audience/format/tone/CTA, beats with optional moment pinning ({mediaId, startSec, endSec}), captions (style + emphasis phrases), seeded graphics (carried VERBATIM as locked clips), exclusions (hard negatives the Director must never author), and gate config (holdAt / autoApprove). Then compose it with POST /projects/:id/compose {briefId} — every field is honored or the compose is refused loudly naming the field. The response carries the brief-time quote (compose + estimated render) to relay BEFORE any metered call. - [Delete a brief](/docs/api/deleteBrief): Remove a video brief the account no longer plans to compose, returning 204 on success. Call it to clear abandoned plans so the project's brief list stays focused on current work. - [Get a brief by id](/docs/api/getBrief): Read one video brief's goal, audience, platform, and other creative direction, along with its cost quote. Call it to review the plan and relay the estimated compose and render cost before composing. - [List briefs (optionally scoped to a project)](/docs/api/listBriefs): DEFAULT lists human-authored briefs only. Machine-minted clip briefs (suggest_briefs output) are opt-in: ?kind=clip lists just them, ?kind=all lists everything. Any other kind value is a 400, never silently empty. - [Edit a brief](/docs/api/updateBrief): Partial update. While an ACTIVE compose job references this brief the edit is refused (409 conflict) — finish, resume, or abandon the job first; the Director never has its input edited out from under it. - **Checkpoints** - [Get a checkpoint packet](/docs/api/getCheckpoint): The full approval packet: the stage artifact under review, presigned storyboard/eval stills, critic verdicts (incl. lock_violation entries), the money triple {thisStep, jobSpendSoFar, estimatedJourneyTotal}, and the recorded decision once resolved. Answer an `awaiting` packet with POST /v1/checkpoints/{id}/resume. - [Read a hosted review packet (token-authenticated page data)](/docs/api/getReviewPacket): The checkpoint page's data: stage artifact (rendered from the packet's own snapshot), presigned stills, critic verdicts, the money triple, the recorded decision once resolved, and the run's v1→vN version stack. Authenticated by the packet's reviewToken (?token=) — the URL from the checkpoint.ready webhook / get_checkpoint. Expired or already-answered packets still render (with their decision), never an error page. - [List checkpoints (scope to a compose job or project)](/docs/api/listCheckpoints): The version stack of approval packets, newest first. Scope with ?composeJobId= to see one run's gate history (v1→vN with per-version status + decisions) or ?projectId= for everything reviewable in a project. - [Record a hosted review decision (the same resume rail)](/docs/api/recordReviewDecision): Record approve / revise / abandon from the hosted page. Server-side this IS POST /v1/checkpoints/{id}/resume — one implementation; the driving agent learns of the decision via the checkpoint webhooks / wait_job. 409 when the packet is no longer awaiting (superseded, expired, or already decided). - [Answer a held checkpoint (approve / revise / abandon)](/docs/api/resumeCheckpoint): The A1 review grammar: one `decision` for the gate, optionally carrying anchored `comments` ({beatId} or {timecodeMs} anchors; per-anchor verdict approve|revise|lock — lock freezes the element contractually) and/or `edits` (your revised stage artifact). `revise` loops IN-JOB: the director revises and re-presents this same gate with a new packet (version+1); the brief quote states the included revision cycles — beyond them, revise is refused 402 with the path forward. `abandon` ends the run. Approve-with-comments is legal: the notes record without gating. - **Compose** - [Cancel an in-flight compose job](/docs/api/cancelCompose): Cancel a running compose so an agent (or a cost guard) can abort a mis-priced or runaway ensemble without waiting out its budget or TTL. Cancellation is confirmed before the job becomes terminal; the compose.cancelled event is then emitted and any linked charge is released. Already-terminal jobs are rejected (422 compose_not_cancellable). - [Start an async Director compose workflow](/docs/api/compose): Async sibling of `composeFromSuggestion`. The Director execution authors a canonical wire-shape Composition and saves it as the project's active composition. Watch progress via the SSE stream at `/v1/projects/:id/compose/:composeJobId/stream`. - [Fetch a compose job's full ensemble state](/docs/api/getComposeJob): Read one compose job's full state: status, request, candidates, and per-criterion scores. Poll it after POST /v1/projects/{id}/compose to follow progress, compare candidates, and catch a job awaiting input. - [List recent compose jobs for a project](/docs/api/listComposeJobs): List up to 50 of a project's most recent compose jobs with status and timing, newest first. Call it to find a job id to inspect or to check for a job still running before starting another. - [Reconcile an uncertain compose start](/docs/api/reconcileComposeDispatch): Reads the recorded execution engine by its persisted key. A missing lookup keeps the job pending; this never dispatches another run. - [Promote a compose candidate to the active composition](/docs/api/selectComposeCandidate): Selects one candidate from a finished compose ensemble and writes it to the project's composition. `selectStrategy` decides how the editor draft interacts with the write (per compose-api-contract.md). - [Stream compose progress (SSE)](/docs/api/streamCompose): Server-Sent Events stream emitting typed `compose_event` frames (per `2026-05-23-compose-api-contract.md` § SSE event types — job_started, candidate_phase_started, candidate_phase_evaluated, candidate_completed, critique_retry_started, winner_selected, job_completed, job_failed). The stream closes once the compose job reaches a terminal status. Required scope: projects:read - **Compositions** - [Apply a batch of operations to a project's composition (or dry-run validate)](/docs/api/applyComposition): Atomically applies an array of CompositionOps. All ops succeed or none do (transactional). A write must carry `if_match`, the composition ETag it observed (409 stale_etag on mismatch), or the stronger `concurrency` admission; with neither it is refused with 428 precondition_required. Pass `dry_run: true` to validate the batch — runs the same apply + projection accept/reject guards WITHOUT persisting, returning `{ valid, errors }` with `locator.op_index` on the first failing op. Both modes may carry `warnings[]` — non-fatal authoring advisories (e.g. a card whose html reads a CSS custom property no token defines). Warnings never block. - [Apply one operation to a project's composition](/docs/api/applyCompositionOp): Applies one CompositionOp. Send `If-Match` with the composition ETag you observed (409 stale_etag on mismatch); without it the write is refused with 428 precondition_required. - [Delete a composition](/docs/api/deleteComposition): Delete a composition and its version history. REFUSES the project's ACTIVE composition (409 composition_active) — make another one active first, or delete the project. - [Derive a reframed sibling composition for a new aspect (multi-format)](/docs/api/deriveComposition): Create a reframed copy of a composition in another aspect ratio, such as 9:16 from 16:9, for multi-format delivery. Send the source's ETag as if_match; the copy is not made active, so pass its id when rendering. - [Get a project's composition](/docs/api/getComposition): Read the editable timeline of a video project, with its ETag in the response header for guarded writes. Call it before editing or rendering; pass compositionId or session_id to read a specific composition or a compose session's scratch copy. - [List a project's compositions](/docs/api/listCompositions): List every composition in a project with its format, ETag, and whether it is the active one. Call it to choose which timeline to edit, preview, or render when a project holds several videos or aspect ratios. - [Create a new composition (video) in a project](/docs/api/newComposition): Add an empty composition to a project, for a second video or another format in the same project. Returns its id and ETag for the first edit; format defaults to the project's, and a project's first composition becomes the active one. - [Replace a project's composition](/docs/api/putComposition): Replaces the whole composition. Send `If-Match` with the ETag you observed (409 stale_etag on mismatch), or `If-None-Match: *` to create the first composition (409 conflict if one exists). Without either the write is refused with 428 precondition_required; `If-Match: *` is refused. - [Validate a composition body without saving it (dry-run)](/docs/api/validateComposition): Dry-run the FULL save-time authoring guard set against a Composition body WITHOUT persisting it and without a project. Runs the same pure, DB-free guards saveComposition enforces — wire shape, primitive membership (unknown_primitive / custom_missing_sourcecode), required-param shape (invalid_primitive_params), clip↔track family (clip_source_track_mismatch), reframe coverage (reframe_coverage_gap), and font admission (font_not_reproducible: a caption/param face that is neither bundled nor sealed in a brand font asset) — and returns ONE shape, `200 { valid, errors[] }`, for BOTH wire-shape and deep-invariant failures (no 400-vs-200 split). `valid:false` lists every authoring error (sanitized envelopes) to fix before save/render. The ONLY checks NOT run here are the two DB-bound ones — trim-bounds (media duration) and image/asset-on-video-track (media kind) — which can only be caught at save/render. - **Consult** - [Ask the multi-agent Director for editing advice (never writes)](/docs/api/consult): Ask the Director for editing advice on the project's current composition — it NEVER saves; you stay the decider. Async: poll the returned job for the advisory envelope. Modes: 'advise' = the planner agent (fast, ~30s-2min) returns a PLAN (framing/cuts/captions/graphics intents) as guidance you re-author from — no grounded scores; 'amend' = the full author→judge→refine loop (minutes) returns a GRADED assessment + an adoptable fix candidate (adopt via POST /compose/jobs/:jobId/select with its candidateIndex). ('explore' — a ranked slate of directions — is coming soon.) - **Critics** - [Register a compose critic](/docs/api/createCritic): Add a custom quality check to the compose loop as rules, a scoring rubric, or your own HTTPS evaluator. A score below its floor routes a refine; re-registering a criticId updates it, and an evaluator's signing secret is returned once. - [Delete a registered critic](/docs/api/deleteCritic): Remove a registered compose critic by its criticId. Call it when a custom rule, rubric, or evaluator should no longer judge this org's compositions; an unknown id returns 404. - [List registered critics (Profile family)](/docs/api/listCritics): Every enabled critic: id, label, tier, phase, floor, and reference media. Rubric text, rules, and evaluator URLs are write-only — registration config comes back, payloads don't. - **Editorial** - [Adopt a legacy authored brief into the shared owner](/docs/api/editorialAdoptLegacyBrief): Move an older brief made through POST /v1/briefs into the editorial flow under the same id, so editorial runs can use it. Clip-derived briefs are not eligible, and adopting a brief twice is a conflict. - [Commit an integrated editorial edit to the saved project composition](/docs/api/editorialApplyComposition): Apply timeline operations and complete the run in one atomic step, the last step of an editorial run. It needs a prior integrate call and the current run revision; further edits need a new run. - [Cancel an active editorial run](/docs/api/editorialCancelRun): End an editorial run that will not be applied, leaving the composition unchanged. Send the run's expectedRevision; only active runs can be cancelled, and continuing the work needs a new run. - [Create a shared authored brief](/docs/api/editorialCreateBrief): Write the creative direction for a video edit: goal, audience, platform, duration, tone, and more. This is the first step of an editorial run, which needs the returned brief id; a commandId makes retries safe. - [Create a shared editorial run](/docs/api/editorialCreateRun): Start an editorial pass that pins a brief, source frame ranges, and a beat outline. Later inspections, findings, and the final edit stay inside those ranges; call it after creating the brief and reading the source. - [Record an evidence-backed finding on an editorial run](/docs/api/editorialFindingsAppend): Save an observation about a source range during an active run, citing 1 to 12 evidence ids and an outcome of useful, nothing_useful, or uncertain. Findings feed the integrate step, which selects or omits them. - [List bounded findings for an editorial run](/docs/api/editorialFindingsList): Page through the findings recorded on an editorial run, up to 100 at a time. Call it before integrating to review what was observed and collect the finding ids to select or omit. - [Read a shared authored brief](/docs/api/editorialGetBrief): Read an editorial brief's goal, audience, format, and other creative direction, plus its current revision. Call it before starting an editorial run, or to get the revision an update must send. - [Read a shared editorial run](/docs/api/editorialGetRun): Read an editorial run's state, pinned inputs, outline, integration, and current revision. Call it to resume work or to get the revision that integrate, cancel, and apply calls must send. - [Read the certified decode representation for a project source](/docs/api/editorialGetRunSource): Get the constant-frame-rate representation of a project's video source: identity, revision, frame rate, and frame count. Call it before POST /v1/editorial/runs to build frame ranges; it is null when none is certified. - [Deliver bounded audio from a certified source interval](/docs/api/editorialInspectAudio): Listen to part of a source: returns up to eight seconds of 16 kHz mono WAV audio as base64, with an evidence id. Call it during an active editorial run for a range inside the pinned inputs. - [Deliver an exact certified source frame](/docs/api/editorialInspectFrame): Look at one exact video frame as a base64 JPEG, with an evidence id for citing it in findings. Call it during an active editorial run; the frame must fall inside the run's pinned source ranges. - [Deliver a verified transcript word span](/docs/api/editorialInspectTranscript): Read up to 100 consecutive transcript words with their mapped frame range and an evidence id. Call it during an active editorial run to verify a quote; the words must fall inside the requested range. - [Record the integration decision for an editorial run](/docs/api/editorialIntegrate): Record which findings the edit uses, why others were omitted, and any unresolved gaps, once inspection is done. This changes no composition: send expectedRevision, then commit with POST /v1/editorial/runs/{runId}/apply. - [List shared briefs for a project](/docs/api/editorialListBriefs): List a project's editorial briefs, up to 20 per page with a cursor; projectId is required. Call it to find a brief to reuse or update before starting an editorial run. - [List delivered evidence for a run](/docs/api/editorialListEvidence): Page through the frames, motion samples, audio, and transcript spans already delivered in an editorial run, up to 100 at a time. Call it to find the evidence ids a finding must cite and to see inspection coverage. - [List shared editorial runs for a project](/docs/api/editorialListRuns): List a project's editorial runs, up to 20 per page with a cursor; projectId is required. Call it to find an active run to continue or to review earlier editing passes. - [Deliver bounded sampled motion frames](/docs/api/editorialSampleMotion): See how a shot moves: returns two or three JPEG frames sampled across a frame range, with an evidence id and coverage receipt. Call it during an active editorial run for a range inside the pinned inputs. - [Update a shared authored brief](/docs/api/editorialUpdateBrief): Replace an editorial brief's goal, audience, format, and other fields. Send its current revision as expectedRevision and the same id in the path and body; call it to refine direction before starting a new run. - **Evidence** - [Compare a certified source frame with an existing composition preview](/docs/api/compareFrames): Returns unaligned PNG evidence at original coordinates. Resolves an existing preview; never renders the composition. Source frame numbers refer to its certified representation, not an inferred original-file timestamp. - [Render one component preview](/docs/api/previewComponent): Queue a preview of ONE org-installed native (version 4) component: a PNG of its middle frame, rendered by the same HyperFrames runtime as the production render. Returns a jobId — wait_job(kind='preview') for the image. Compile/runtime failures land on the job terminal with the sanitized author-fixable message. - [Queue still-frame evidence for a composition](/docs/api/previewFrameJob): Resolve and freeze the exact authored target, then queue durable still capture. Returns immediately; poll the generic job with wait_job(kind='preview_frame'). One successful request is one compose_capture operation regardless of timestamp count. - [Score a composition (the standalone sighted judge)](/docs/api/scoreComposition): Queue the server-side judge: it samples eval beats, renders them, and grades editorial/spatial/brand/caption (0–10 + weighted composite + worst-first critique). Your REGISTERED CRITICS run too (register_critic) — rules + rubric verdicts ride the result as clientScores, exactly like the Director's gates evaluate them (evaluator-webhook critics run in the Director lane only). Returns a jobId — wait_job(kind='verify') for the result, which ALSO carries a checkpointId: the verdicts mint a durable kind:'score' Checkpoint (the same evidence noun the Director's gates produce). Stateless — nothing to open, warm or close; the compose_verify meter fires on the job's success terminal. - **Exports** - [Cancel an in-flight export](/docs/api/cancelExport): Stop an export that is still running and get back the updated job. Call it when an FCPXML, Premiere, or video clip export is no longer needed; a finished export is refused, and a 503 means the cancel was not delivered, so retry. - [Create a Final Cut Pro export](/docs/api/createFcpxmlExport): Export the project as a Final Cut Pro XML (FCPXML) timeline — eject the agent-authored edit into a professional NLE for human finishing, preserving clips, trims, and timeline structure. Async: poll GET /projects/:id/exports/:exportId for the download URL. - [Create a Premiere Pro export](/docs/api/createPremiereExport): Export the project to Adobe Premiere Pro — eject the agent-authored edit into a professional NLE for human finishing, preserving clips, trims, and timeline structure. Async: poll GET /projects/:id/exports/:exportId for the download URL. - [Create a video clip export](/docs/api/createVideoClipExport): Export one suggestion as an H.264/AAC MP4 through the keyed NLE workflow. Poll getExport for its artifact. - [Get an export job](/docs/api/getExport): Check an export job's status and progress from 0 to 1, and get its output URL, size, and duration once complete. Poll it after starting an FCPXML, Premiere, or video clip export. - [Retry an export's admitted specification](/docs/api/retryExport): Create a new keyed export from the original immutable snapshot in its admitted project. Use Idempotency-Key to safely replay the HTTP request. Priced like the export it repeats and charged when the retry completes. - **Fonts** - [List the font faces the renderer can actually draw](/docs/api/listRenderFonts): The renderer's admitted font set: per family the exact name authoring accepts, the weight ranges a shipped file declares, the styles bytes exist for, the caption default weights, and whether the bytes are bundled or an aliased metric-compatible stand-in. Choose from here and validate_composition will not refuse the face. Unlike POST /fonts/search (which searches the GOOGLE catalog) this is what the render page can rasterize. `manifestVersion` identifies the exact table and moves only when the admitted set does. Covers the BUNDLED set only — a brand kit's sealed faces are per-org and per-render. - [Search web font families by name/style](/docs/api/searchFonts): Search the Google Fonts web-font catalog by keyword. Returns matching font families (family name + category + available variants + a css2 stylesheet URL). DISCOVERY ONLY, and this is NOT the set the renderer can draw: a cloud render draws only the faces GET /v1/fonts lists, or a face sealed in a brand kit font asset. Naming any other family in captions/params fails validate_composition with font_not_reproducible. Read GET /v1/fonts to choose a family AND an admitted weight and style before authoring. Read-only and free; results are cached server-side. An empty `results` array means no match (or the upstream catalog was unavailable). - **Jobs** - [Cancel an async job](/docs/api/cancelJob): Cancel a running async job so an agent can abort a mis-priced/runaway operation without waiting out its TTL. Cancellation is durable and never meters. Already-terminal jobs are rejected (422 job_not_cancellable). - [Get an async job's status and result](/docs/api/getJob): Read one async job — the uniform status/result resource behind every long-running operation. Poll until `status` is terminal (`succeeded` | `failed` | `cancelled`), then read `result` (kind-specific payload) or `error` (stable code + message). `job_timeout` means the executor died mid-run and the stall sweep reaped the job — re-enqueue the operation to retry. - **Registry** - [Acquire exact upstream source into an owned receipt](/docs/api/acquireRegistryItem): Explicitly acquires the selected manifest and dependency closure through the pinned installer in disposable staging, retaining original and transformed bytes in an organization-owned immutable bundle. It does not execute downloaded source or automatically convert unsupported runtimes. Continue with existing component/template authoring operations and exact provenance association; acquisition alone does not qualify visual fidelity. - [Read an owned acquisition and bounded source bytes](/docs/api/getRegistryAcquisition): Reads only this organization’s immutable receipt, verifies archive/source closure, and returns exact bounded source text plus an expiring owned archive link. Large or binary files remain explicitly identified in the file manifest. - [Inspect exact external registry source metadata](/docs/api/getRegistryItem): Reads the complete maintained item manifest at one fixed inventory/source snapshot, including examples. Examples may be inspectable while init acquisition remains explicitly unsupported. An external preview is not CueFrame-rendered evidence. - [Refresh the guarded registry metadata snapshot](/docs/api/refreshRegistrySnapshot): Resolves upstream main once to an exact source commit and captures coherent inventory/manifests with the pinned client. Publication requires the observed snapshot and head revision (both null for first selection). Refresh never edits owned source heads or placements. Metadata and preview changes are reported independently; actual source-byte changes remain unobserved until explicit acquisition. - [Discover external HyperFrames candidates](/docs/api/searchRegistryItems): External source discovery through the pinned maintained client. Supply all exact snapshot fields or omit all to select the current organization snapshot. Results retain upstream ranking, search scope, limitations and unverified upstream preview provenance. Discovery never installs source or marks it CueFrame compatible. - **Resources** - [Import a stock candidate or a curated SFX-pack sound](/docs/api/importResource): Two lanes. STOCK { projectId, candidateId }: import a candidate returned by search_resources into a project as an org-owned media item (preserving provider/externalId/license provenance; bytes deduped across orgs). Async: returns { id, status:'importing' }; status flips to complete when the import finishes (poll GET /media/:id). A candidate whose 7-day search cache has expired returns 422 — re-search. PACK { kind:"sfx-pack", id: }: mint/return the org media item for a curated CC0 SFX-pack sound (soundId from list_catalog's sfx[]) — returns { id, status:'ready' } immediately to place as a normal sfx clip. Idempotent per (org, soundId); an unknown soundId is a 422. Pack imports are FREE: no plan feature required, and an x402 payment is released unsettled (no charge). PRICE of a stock import for a keyed (API-key / session) caller: 0 credits — the resource_import entitlement is a plan grant, not a meter (get_account reports `entitlements.resource_import.listUsdPerUnit: 0`); the imported bytes count toward the `storage` gauge. Only an unkeyed x402 caller pays the $0.01 import tier. - [Search stock media (Pexels / Pixabay / Freesound / Klipy)](/docs/api/searchResources): Search licensed stock media by keyword. Pass `query` for one search, or `queries[]` (≤10) to run a batch in ONE call — the batch returns `results[]`, one entry per query in order, each with its own `candidates` (and an `error` string if that single query failed; one bad query never discards the rest). `kind` selects the corpus (video/photo default to Pexels; Pixabay is explicitly selectable; sfx → Freesound CC0-only; gif → Klipy); defaults to video. Returns ranked candidates each carrying an opaque `candidateId` — pass it to import_resource to bring the asset into a project. Free + rate-limited; results are cached for 7 days, after which a candidateId must be refreshed by searching again. For sfx, bound the result by clip length with `durationSec` — impacts/ticks ≈ 0–2s, risers/whooshes ≈ 2–8s, ambients unbounded. For video, use minWidth/minHeight to exclude smaller renditions. - **Templates** - [Apply a template to a project](/docs/api/applyTemplate): Bind the template's parameters and write the result as the project's timeline, in one Studio command: the server installs the template's components, writes its brand kit (or the preset's, or `brandKitId`'s) onto the project and saves the bound composition. Media values are `{ mediaId }` (must be complete), `{ url }` (an https URL imported once per org) or `{ sample: true }` (the parameter's pinned sample). While an import runs the answer is 202 with `pendingMediaIds`; call again once they are complete. A public slug is imported into this org on first use. Builtin packages require the documentSha256 returned by resolveBuiltinComponent and insert with startTime/idPrefix, expectedRevision and commandId; insertion preserves existing tracks. Over an existing composition `expectedRevision` is required (428 precondition_required without it, 409 when stale); a project with none needs it only for insertion. - [Cancel template preparation](/docs/api/cancelTemplateJob): Stop a template preparation that is still running. Call it when the new project is no longer wanted; a job that is already ready, failed, or cancelled is returned unchanged. - [Cancel a template render](/docs/api/cancelTemplateRender): Before the render job exists the workflow is cancelled and the row closed; after, the render job's own cancel runs and the row mirrors it. - [Reserve a bounded portable template package upload](/docs/api/createTemplatePackageUpload): Organization-library operation. Project-bound editor credentials are refused. Reserves exact SHA256/length for a single application/zip PUT; the grant is not a template import. - [Render a template to an MP4 with a share link](/docs/api/createTemplateRender): Bind the template's parameters and render the result under the org's system project, without touching any project of yours: one row per request, rendered through the render pipeline and reachable at `shareUrl` (302 to the MP4 while it is complete) and `posterUrl`. Media values are `{ mediaId }` (must be complete), `{ url }` (https, imported once per org) or `{ sample: true }`; imports are awaited by the render. Priced as a render; an x402 caller's render expires with their workspace. Send an Idempotency-Key per row to make retries safe. - [Delete a template](/docs/api/deleteTemplate): Existing renders keep their snapshots and share links; new renders and applies of this id answer 404. - [Export an exact saved project as a portable template package](/docs/api/exportProjectTemplatePackage): Reads the saved project at expectedRevision and uses the maintained extractTemplate owner. Caller controls select existing parameter sites; caller composition, component source, media sample and provenance assertions are refused. Project-bound editors may export only their exact bound project. - [Read a template document](/docs/api/getTemplate): By org template id or public slug. A public slug this org never used is read from the catalog and stored nowhere. - [Read template preparation status](/docs/api/getTemplateJob): Check a template preparation job's status, current stage, and project id, or its error if it failed. Poll it after POST /v1/templates/{id}/instantiate until the status is ready. - [Refresh the download grant for an owned template package receipt](/docs/api/getTemplatePackageDownload): The receipt owner verifies exact retained archive/document authority before issuing a short-lived URL. A project-bound editor must supply the exact ready export jobId belonging to its bound source project and receipt. - [Read a template render](/docs/api/getTemplateRender): Check a template render's status and get its share link and poster URL, or its error if it failed. Poll it after POST /v1/templates/{id}/renders to learn when the video is ready to share. - [Import an uploaded template package into the organization library](/docs/api/importTemplatePackage): Consumes the authenticated actor package upload reservation. No caller storage keys, document bodies or provenance assertions are accepted. Existing destination slugs require the exact expected version and document digest. Poll getTemplateJob; a ready package remains destination-owned. Project-bound editor credentials are refused. - [Start a new project from a pinned template](/docs/api/instantiateTemplate): Create a new project from a template, binding its values and media with an optional preset and brand kit. Async: requires an Idempotency-Key header and returns 202 with a job; poll GET /v1/template-jobs/{jobId} for the project id. - [List this org's templates](/docs/api/listTemplates): Page through the video templates saved in this account, newest first, as summaries without their full documents. Call it to find a template id for rendering, applying to a project, or starting a new project. - [Publish a template document, or import a public catalog slug](/docs/api/publishTemplate): Store a template document for this org (the kernel validates its schema and every `{{name}}` reference; a republish of the same slug bumps its version), or import a slug from the public catalog (cueframe-ai/cueframe-templates) as this org's copy. The document is capped at 1 MiB. With `dryRun: true` nothing is stored: the answer is 200 with the kernel's problems as data, for the document alone or, when `values`, `media` or `preset` are given, for those inputs bound against this org's media rows. - [Retry a failed template preparation](/docs/api/retryTemplateJob): Resume a failed template preparation from the stage that failed, re-entering import if processing failed. Only failed jobs restart; a job in any other state is returned unchanged, so read its status first. - [Revoke a template render's share link](/docs/api/revokeTemplateRender): The share link and poster answer 404 from now on; the render's output is kept. A render still in flight is cancelled first. - **Traces** - [Attach production scores to one of your director traces](/docs/api/scoreTrace): Record 1–10 named scores (0..1) on a trace the CueFrame gateway produced for YOUR director run — the trace id is the `trace_id` the client stamped on that run's requests. Only the trace's own user may score it; any other trace id answers 404. Scores are accepted asynchronously and acknowledged with 202. Free. - **Other** - [API reference](/docs/api): The full CueFrame REST surface, generated from the OpenAPI spec — media, projects, compositions, compose, renders, and more.