{"openapi":"3.1.0","info":{"title":"CueFrame API","description":"CueFrame public REST API. Authenticate with `Authorization: Bearer cf_live_*` / `cf_test_*` keys, or use x402 EIP-3009 payments on priced endpoints. Every endpoint is org-scoped; cross-org access returns 404 (not 403) to avoid leaking resource existence.\n\nSee: https://docs.cueframe.ai","version":"v1","contact":{"name":"CueFrame","url":"https://cueframe.ai","email":"support@cueframe.ai"},"license":{"name":"Apache-2.0","identifier":"Apache-2.0"}},"servers":[{"url":"https://api.cueframe.ai","description":"Production"}],"tags":[{"name":"media","description":"Media items — uploads, generation, transcripts."},{"name":"clips","description":"Clipping capability — find publishable moments in long-form media (suggestions) and compose from a chosen moment."},{"name":"projects","description":"Projects container + metadata."},{"name":"renders","description":"Render jobs — create, status, stream, cancel, refresh URL."},{"name":"sessions","description":"Multi-angle session recordings + mux."},{"name":"components","description":"Built-in + org-installed components."},{"name":"brand-kits","description":"Org-scoped brand kits (read-only)."},{"name":"webhooks","description":"Outbound webhooks (HMAC-signed, retried, dead-lettered)."},{"name":"health","description":"Unauthenticated health + introspection."},{"name":"skills","description":"Public agent skills (SKILL.md) — discovery + markdown."},{"name":"compose-session","description":"Warm reactive session: render frames, capture stills, and verify (judge-score) a composition in a loop."},{"name":"workspace","description":"One-call editing handle: mint a project + import its source URL in a single request."},{"name":"account"},{"name":"api-keys"},{"name":"billing"},{"name":"briefs"},{"name":"checkpoints"},{"name":"compose"},{"name":"compositions"},{"name":"consult"},{"name":"critics"},{"name":"evidence"},{"name":"exports"},{"name":"fonts"},{"name":"jobs"},{"name":"resources"},{"name":"selector"},{"name":"templates"},{"name":"traces"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"cf_live_* or cf_test_*","description":"API key auth. Prefix `cf_live_` for production orgs, `cf_test_` for sandbox."},"x402":{"type":"apiKey","in":"header","name":"PAYMENT-SIGNATURE","description":"x402 v2 payment header (EIP-3009 USDC on Base; base64 PaymentPayload). Returned 402 Payment-Required if absent on priced endpoints."}},"schemas":{"AccountResponse":{"type":"object","properties":{"generationLimit":{"anyOf":[{"type":"object","properties":{"applies":{"type":"boolean"},"unit":{"type":"string","const":"cents_of_provider_cost"},"cap":{"type":["number","null"]},"spent":{"type":["number","null"]},"remaining":{"type":["number","null"]}},"required":["applies","unit","cap","spent","remaining"],"additionalProperties":false},{"type":"null"}],"description":"Separate lifetime generation cap before a credit-pack purchase. Wallet balance is still shared; generation must also fit this remaining provider-cost allowance. null means unknown."},"orgId":{"type":"string","description":"The org this API key is bound to — resolved server-side from the Authorization credential, NEVER from the request body/query."},"displayName":{"description":"Org/customer display name from the billing record; null when not set or unknown.","type":["string","null"]},"plan":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"Plan/product id (e.g. free, pro, business, studio)."},"name":{"description":"Plan display name.","type":["string","null"]}},"required":["id","name"],"additionalProperties":false},{"type":"null"}],"description":"The customer's current base plan/tier. null = unknown (billing not configured, or no active plan resolvable yet)."},"entitlements":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/EntitlementEntry"},"description":"Per-feature entitlements keyed by featureId. Covers the billing-gated capabilities: `exports` gates create_render AND generate_media output; `compose` gates compose; `brand_kits` gates create_brand_kit; `resource_import` gates import_resource (a boolean grant: `listUsdPerUnit` 0 — stock search and import cost no credits for a keyed caller); plus ai_tokens/storage/compose_verify/compose_capture/etc. Read `listUsdPerUnit` for what one unit costs before you spend it. Most capabilities are CREDIT-FUNDED — `included` is true and the real limit is `balance`, drawn from the shared wallet named in `fundedBy` (`credits` — generation included; a free org is additionally bounded by a generation cap). So read `balance`, not `included`, to decide whether you can afford a call; `included:false` means the plan genuinely lacks the feature. Check BEFORE a metered call to avoid a mid-workflow 402 billing_required (whose error `details.featureId` names the gating feature)."},"costCeilings":{"type":"object","properties":{"generateMediaUsdPerCall":{"description":"Per-call USD ceiling for generate_media: a generation whose ESTIMATE exceeds this 402s (generation_budget_exceeded) before any spend. Right-size the prompt/duration under this. null = unknown.","type":["number","null"]}},"required":["generateMediaUsdPerCall"],"additionalProperties":false,"description":"Discoverable per-call cost ceilings so an agent can price/right-size a request before a guaranteed 402."},"billingConfigured":{"type":"boolean","description":"false = billing is not configured in this environment, so plan/entitlement values are best-effort and may be null (unknown), not authoritative."},"surfaces":{"type":"object","properties":{"console":{"type":"string","description":"Origin of the authenticated web console."},"usage":{"type":"string","description":"Browser URL for the usage ledger."},"billing":{"type":"string","description":"Browser URL for plan and credits."},"apiKeys":{"type":"string","description":"Browser URL for minting and revoking API keys."},"project":{"type":"null","description":"No per-project browser view exists yet, so there is no URL to hand a user for a project or its composition. Stated as an explicit null so a client does not construct a route that 404s (CUE-19). Show a rendered frame (preview_frame) or a completed render instead."}},"required":["console","usage","billing","apiKeys","project"],"additionalProperties":false,"description":"The browser URLs that actually exist, so an agent asked to \"show me\" can hand the user a real link instead of guessing one from an id. A null means the surface is not built, not that it is hidden from this key."}},"required":["generationLimit","orgId","displayName","plan","entitlements","costCeilings","billingConfigured","surfaces"],"additionalProperties":false,"description":"Account discovery for the authenticated key: identity + plan + entitlements + cost ceilings + the browser surfaces that exist. Read this to see what your plan/credits allow before a metered call (create_render / compose / generate_media / create_brand_kit)."},"EntitlementEntry":{"type":"object","properties":{"featureId":{"type":"string","description":"Stable billing feature id."},"name":{"type":"string","description":"Human-readable feature name."},"type":{"type":"string","enum":["metered","boolean","credit_system"],"description":"metered = a depleting/gauge quota (has balances); boolean = an on/off plan grant; credit_system = a spendable wallet the metered lines draw from."},"unit":{"anyOf":[{"type":"string","enum":["cents","count","minutes","gb"]},{"type":"null"}],"description":"What `balance`/`includedUsage`/`usage` are COUNTED IN — do not assume. `exports` is output-MINUTES (not a number of renders), `compose`/`ai_tokens`/`compose_verify`/`generate` are CENTS of spend (not a number of calls), `compose_capture` is a count of stills, `storage` is GB, a credit system is cents (1 credit = $0.01). null = boolean feature, nothing to count."},"included":{"description":"Does the CURRENT plan grant this feature? For a credit-funded feature (see `fundedBy`) this is true whenever the plan grants the funding wallet — spend is then bounded by `balance`, not by inclusion. false = not on this plan (a create gated on it 402s billing_required); null = unknown (billing not configured / no live data).","type":["boolean","null"]},"unlimited":{"description":"Metered only: the plan grants an effectively-unlimited allowance. null = unknown / boolean feature.","type":["boolean","null"]},"balance":{"description":"Metered only: remaining balance for the current period, in THIS feature's unit. For a credit-funded feature it is the funding wallet's balance restated at `creditCost` credits per unit — a SHARE of a pool, not a private allowance. null = unknown / boolean feature.","type":["number","null"]},"includedUsage":{"description":"Metered only: the plan's included allowance (the period limit), in this feature's unit. null = unknown / boolean feature.","type":["number","null"]},"usage":{"description":"Metered only: amount consumed this period, in this feature's unit. null = unknown / boolean feature.","type":["number","null"]},"nextResetAt":{"description":"Metered only: epoch-ms when the period balance resets. null = unknown / no scheduled reset.","type":["number","null"]},"fundedBy":{"description":"The credit system that actually pays for this feature (always `credits` — there is one wallet). Non-null means the feature has NO separate allowance: its `balance` restates that shared wallet, and every other feature with the same `fundedBy` competes for the same money. null = the plan grants this feature directly.","type":["string","null"]},"creditCost":{"description":"Credits consumed per ONE unit of this feature (exports 50 = $0.50 per 1080p output-minute; compose_capture 2 = $0.02 per still). null = not credit-funded.","type":["number","null"]},"listUsdPerUnit":{"description":"LIST price in USD of ONE unit of this feature (see `unit`) — the quote to read BEFORE a call. Credit-funded: `creditCost`/100 (exports 0.5 per 1080p output-minute; compose_capture 0.02 per still; compose/ai_tokens/generate 0.015 per cent of provider cost). 0 = the plan grants this feature and it draws NO credits (resource_import: stock search AND import are free for a keyed caller, bytes count toward `storage`; brand_kits). null = not quotable up front (a wallet, a gauge, or a feature the plan does not grant).","type":["number","null"]}},"required":["featureId","name","type","unit","included","unlimited","balance","includedUsage","usage","nextResetAt","fundedBy","creditCost","listUsdPerUnit"],"additionalProperties":false,"description":"A single feature's entitlement: whether the plan includes it, remaining/limit when metered, and the per-unit list price to quote before a call"},"ApiKeyCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"permissions":{"type":"object","propertyNames":{"type":"string","enum":["media","sessions","projects","renders","webhooks","billing"]},"additionalProperties":{"minItems":1,"type":"array","items":{"type":"string","enum":["read","write"]}},"description":"Resource → actions grant. Resources: media, sessions, projects, renders, webhooks, billing. Actions: read, write. Least-privilege — grant only what's needed (billing:write is required to start a checkout)."},"expiresIn":{"description":"Lifetime in seconds; omit for no expiry.","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["name","permissions"],"additionalProperties":false},"ApiKeyResponse":{"type":"object","properties":{"key":{"type":"string","description":"The full secret key (cf_test_… / cf_live_…). Shown ONCE — store it now."},"id":{"type":"string"},"prefix":{"type":"string"},"start":{"type":"string","description":"First chars of the key, for later identification."}},"required":["key","id","prefix","start"],"additionalProperties":false},"AudioPaletteEntry":{"type":"object","properties":{"ref":{"type":"string","description":"Placement handle: a pack soundId/bedId, or an org media id."},"role":{"type":"string","enum":["vo","music","sfx","ambience"],"description":"Declared role for mix policy."},"envelopeClass":{"type":"string","enum":["transient","sweep","ambient"],"description":"Coarse envelope shape — the browse grouping."},"description":{"type":"string"},"durationSec":{"type":"number"},"evidence":{"type":"object","properties":{"envelopeClass":{"type":"string","enum":["transient","sweep","ambient"]},"attackMs":{"type":"number"},"spectralCentroidHz":{"type":"number"},"meanVolumeDb":{"type":"number"},"maxVolumeDb":{"type":"number"}},"required":["envelopeClass"],"additionalProperties":false,"description":"Envelope probe evidence (always carries envelopeClass)."},"source":{"type":"string","enum":["pack","org","generated"],"description":"Provenance discriminant."},"license":{"type":"string","description":"\"CC0\" (pack), \"org-owned\"/a CC token (org), or \"generated\"."},"provenance":{"type":"string","description":"Human-legible provenance (pack attribution / org-owned / generator + prompt)."},"bpm":{"description":"Tempo — present for music-role entries.","type":"number"},"mood":{"description":"Editorial mood tags — present for pack music beds.","type":"array","items":{"type":"string"}}},"required":["ref","role","envelopeClass","description","durationSec","evidence","source","license","provenance"],"additionalProperties":false},"BillingPlanEntry":{"type":"object","properties":{"id":{"type":"string","description":"Billing catalog product id (e.g. pro, pro_yearly)."},"tier":{"type":"string","description":"Plan tier: pro | business | studio."},"name":{"type":"string"},"interval":{"type":"string","description":"month | year."},"priceUsd":{"type":"number","description":"Price in USD for the interval."}},"required":["id","tier","name","interval","priceUsd"],"additionalProperties":false},"BillingPlansResponse":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/BillingPlanEntry"},"description":"Every purchasable {tier, interval} and its product id."},"billingConfigured":{"type":"boolean"}},"required":["plans","billingConfigured"],"additionalProperties":false},"BrandKitCreateRequest":{"type":"object","properties":{"kitId":{"type":"string","minLength":1,"maxLength":200},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"tagline":{"type":"string","maxLength":500},"secondaryTagline":{"type":"string","maxLength":500},"colors":{"type":"object","properties":{"primary":{"type":"string","minLength":1},"secondary":{"type":"string","minLength":1},"accent":{"type":"string","minLength":1},"background":{"type":"string","minLength":1},"text":{"type":"string","minLength":1}},"required":["primary","secondary","accent","background","text"],"additionalProperties":false},"extraColors":{"type":"array","items":{"type":"object","properties":{"hex":{"type":"string","minLength":1},"label":{"type":"string","minLength":1},"usage":{"type":"string"}},"required":["hex","label"],"additionalProperties":false}},"headingFont":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontWeight":{"type":"number"}},"required":["fontFamily","fontWeight"],"additionalProperties":false},"bodyFont":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontWeight":{"type":"number"}},"required":["fontFamily","fontWeight"],"additionalProperties":false},"voiceGuidelines":{"type":"string","maxLength":5000},"syncCaptions":{"type":"boolean"},"captionProfile":{"type":"object","properties":{"fontFamily":{"type":"string"},"fontSize":{"type":"number"},"fontWeight":{"type":"number"},"color":{"type":"string"},"highlightColor":{"type":"string"},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"position":{"type":"string","enum":["top","center","bottom"]},"textTransform":{"type":"string","enum":["none","uppercase"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number"},"entranceStaggerMs":{"type":"number"},"exitMs":{"type":"number"},"emphasisColor":{"type":"string"},"emphasisScale":{"type":"number"},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"emphasisTextTransform":{"type":"string","enum":["none","uppercase"]},"emphasisLetterSpacing":{"type":"number"},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"}},"additionalProperties":false},"motion":{"type":"object","properties":{"duration":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","ease-in","ease-out","ease-in-out"]},{"type":"object","properties":{"kind":{"type":"string","const":"cubic-bezier"},"x1":{"type":"number"},"y1":{"type":"number"},"x2":{"type":"number"},"y2":{"type":"number"}},"required":["kind","x1","y1","x2","y2"],"additionalProperties":false}]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"staggerMs":{"type":"number"},"exitMs":{"type":"number"}},"additionalProperties":false},"logo":{"type":"object","properties":{"src":{"type":"string","minLength":1},"alt":{"type":"string"},"placement":{"type":"string","enum":["tl","tr","bl","br"]},"sizePct":{"type":"number"}},"required":["src"],"additionalProperties":false},"intro":{"type":"object","properties":{"kind":{"type":"string","enum":["card","video"]},"src":{"type":"string","minLength":1},"title":{"type":"string"},"subtitle":{"type":"string"},"durationMs":{"type":"number"}},"required":["kind"],"additionalProperties":false},"outro":{"type":"object","properties":{"kind":{"type":"string","enum":["card","video"]},"src":{"type":"string","minLength":1},"title":{"type":"string"},"subtitle":{"type":"string"},"durationMs":{"type":"number"}},"required":["kind"],"additionalProperties":false},"watermark":{"type":"object","properties":{"src":{"type":"string","minLength":1},"opacity":{"type":"number","minimum":0,"maximum":1},"placement":{"type":"string","enum":["tl","tr","bl","br"]}},"required":["src"],"additionalProperties":false},"spacing":{"type":"object","properties":{"base":{"type":"number"},"lg":{"type":"number"},"sm":{"type":"number"}},"additionalProperties":false},"sizing":{"type":"object","properties":{"fontSizeHeading":{"type":"number"},"fontSizeBody":{"type":"number"},"fontSizeLabel":{"type":"number"},"borderRadius":{"type":"number"}},"additionalProperties":false},"audio":{"type":"object","properties":{"sfxIntensity":{"type":"string","enum":["off","light","standard","dense"]},"musicEnabled":{"type":"boolean"},"musicMood":{"type":"string","maxLength":300},"sonicLogo":{"description":"A brand sound signature bound to the intro/outro bookend. `ref` = a palette reference; bound only when the kit carries the matching bumper (intro/outro), else a non-blocking advisory.","type":"object","properties":{"ref":{"type":"string","minLength":1},"placement":{"type":"string","enum":["intro","outro","both"]},"offsetMs":{"type":"integer","minimum":0,"maximum":10000}},"required":["ref","placement"],"additionalProperties":false},"uiSoundSet":{"description":"Per-family SFX overrides (the brand's own tick/pop/…). Highest-priority tier over the org palette + pack default in the compose SFX draw.","type":"object","properties":{"tick":{"type":"string","minLength":1},"pop":{"type":"string","minLength":1},"impact":{"type":"string","minLength":1},"confirm":{"type":"string","minLength":1},"error":{"type":"string","minLength":1},"whoosh":{"type":"string","minLength":1},"riser":{"type":"string","minLength":1}},"additionalProperties":false},"bedStyle":{"description":"Preferred music bed (`bedId`) or a style hint (`genre` / `bpmRange`). Surfaced for driving agents; compose does not auto-select a pack bed.","type":"object","properties":{"bedId":{"type":"string","minLength":1},"genre":{"type":"string","maxLength":120},"bpmRange":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"],"additionalProperties":false}},"additionalProperties":false},"ambiencePreference":{"description":"Preferred ambience bed (`{ref}`) or explicit null (opt-out). Surfaced for driving agents; compose has no ambience auto-placement.","anyOf":[{"type":"object","properties":{"ref":{"type":"string","minLength":1}},"required":["ref"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"exemplarKeys":{"maxItems":24,"type":"array","items":{"type":"string","minLength":1}},"contactSheetKey":{"type":"string","minLength":1},"motifs":{"maxItems":24,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":40},"observed":{"type":"string","minLength":1,"maxLength":500},"body":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["kind","html"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["kind","primitiveId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["kind","componentId"],"additionalProperties":false}],"type":"object"},"motion":{"type":"object","properties":{"preset":{"type":"string","enum":["fade-up","slide-in-left","slide-in-right","scale-pop","stagger-reveal"]},"enterMs":{"type":"integer","minimum":0,"maximum":5000},"exitMs":{"type":"integer","minimum":0,"maximum":5000},"staggerMs":{"type":"integer","minimum":0,"maximum":2000},"confidence":{"type":"string","enum":["high","low"]}},"required":["preset"],"additionalProperties":false},"role":{"type":"string","enum":["title-card","stat","lower-third","pull-quote","hero","logo-tag","enumeration","sequence","comparison"]},"zone":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"w":{"type":"number"},"h":{"type":"number"}},"required":["x","y","w","h"],"additionalProperties":false},"evidence":{"maxItems":24,"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}},"diffScore":{"type":"number","minimum":0,"maximum":1},"coverage":{"type":"string","enum":["reproduced","approximated","skipped"]},"skipReason":{"type":"string","maxLength":300}},"required":["id","observed","body","role","coverage"],"additionalProperties":false}},"styleRubric":{"type":"string","maxLength":4000},"density":{"type":"object","properties":{"graphicsPerMin":{"type":"number","minimum":0,"maximum":60},"maxSimultaneous":{"type":"integer","minimum":1,"maximum":6}},"required":["graphicsPerMin","maxSimultaneous"],"additionalProperties":false},"inspiration":{"type":"object","properties":{"sources":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string"}},"extractedAt":{"type":"number"},"extractionVersion":{"type":"string","minLength":1,"maxLength":60}},"required":["sources","extractedAt","extractionVersion"],"additionalProperties":false}},"required":["kitId","name","colors","headingFont","bodyFont"],"additionalProperties":false,"description":"POST /brand-kits body. Org/user are server-resolved; never accepted from the body."},"BrandKitExemplarsRequest":{"type":"object","properties":{"motifId":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":12}},"additionalProperties":false,"description":"POST /brand-kits/{id}/exemplars body — select which exemplar frames to presign."},"BrandKitExemplarsResponse":{"type":"object","properties":{"exemplars":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"url":{"type":"string"}},"required":["index","url"],"additionalProperties":false}},"contactSheetUrl":{"type":"string"}},"required":["exemplars"],"additionalProperties":false},"BrandKitListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BrandKitResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"BrandKitResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"tagline":{"type":["string","null"]},"colors":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"extraColors":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"],"additionalProperties":false}},"fonts":{"type":"object","properties":{"heading":{"anyOf":[{"type":"object","properties":{"family":{"type":"string"},"weight":{"type":["number","string"]}},"required":["family"],"additionalProperties":false},{"type":"null"}]},"body":{"anyOf":[{"type":"object","properties":{"family":{"type":"string"},"weight":{"type":["number","string"]}},"required":["family"],"additionalProperties":false},{"type":"null"}]}},"required":["heading","body"],"additionalProperties":false},"voiceGuidelines":{"type":["string","null"]},"captions":{"type":"object","properties":{"sync":{"type":"boolean"},"profile":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]}},"required":["sync","profile"],"additionalProperties":false},"motion":{"type":"object","properties":{"duration":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","ease-in","ease-out","ease-in-out"]},{"type":"object","properties":{"kind":{"type":"string","const":"cubic-bezier"},"x1":{"type":"number"},"y1":{"type":"number"},"x2":{"type":"number"},"y2":{"type":"number"}},"required":["kind","x1","y1","x2","y2"],"additionalProperties":false}]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"staggerMs":{"type":"number"},"exitMs":{"type":"number"}},"additionalProperties":false},"logo":{"type":"object","properties":{"src":{"type":"string"},"alt":{"type":"string"},"placement":{"type":"string","enum":["tl","tr","bl","br"]},"sizePct":{"type":"number"}},"required":["src"],"additionalProperties":false},"intro":{"type":"object","properties":{"kind":{"type":"string","enum":["card","video"]},"src":{"type":"string"},"title":{"type":"string"},"subtitle":{"type":"string"},"durationMs":{"type":"number"}},"required":["kind"],"additionalProperties":false},"outro":{"type":"object","properties":{"kind":{"type":"string","enum":["card","video"]},"src":{"type":"string"},"title":{"type":"string"},"subtitle":{"type":"string"},"durationMs":{"type":"number"}},"required":["kind"],"additionalProperties":false},"watermark":{"type":"object","properties":{"src":{"type":"string"},"opacity":{"type":"number"},"placement":{"type":"string","enum":["tl","tr","bl","br"]}},"required":["src"],"additionalProperties":false},"spacing":{"type":"object","properties":{"base":{"type":"number"},"lg":{"type":"number"},"sm":{"type":"number"}},"additionalProperties":false},"sizing":{"type":"object","properties":{"fontSizeHeading":{"type":"number"},"fontSizeBody":{"type":"number"},"fontSizeLabel":{"type":"number"},"borderRadius":{"type":"number"}},"additionalProperties":false},"audio":{"type":"object","properties":{"sfxIntensity":{"type":"string","enum":["off","light","standard","dense"]},"musicEnabled":{"type":"boolean"},"musicMood":{"type":"string","maxLength":300},"sonicLogo":{"description":"A brand sound signature bound to the intro/outro bookend. `ref` = a palette reference; bound only when the kit carries the matching bumper (intro/outro), else a non-blocking advisory.","type":"object","properties":{"ref":{"type":"string","minLength":1},"placement":{"type":"string","enum":["intro","outro","both"]},"offsetMs":{"type":"integer","minimum":0,"maximum":10000}},"required":["ref","placement"],"additionalProperties":false},"uiSoundSet":{"description":"Per-family SFX overrides (the brand's own tick/pop/…). Highest-priority tier over the org palette + pack default in the compose SFX draw.","type":"object","properties":{"tick":{"type":"string","minLength":1},"pop":{"type":"string","minLength":1},"impact":{"type":"string","minLength":1},"confirm":{"type":"string","minLength":1},"error":{"type":"string","minLength":1},"whoosh":{"type":"string","minLength":1},"riser":{"type":"string","minLength":1}},"additionalProperties":false},"bedStyle":{"description":"Preferred music bed (`bedId`) or a style hint (`genre` / `bpmRange`). Surfaced for driving agents; compose does not auto-select a pack bed.","type":"object","properties":{"bedId":{"type":"string","minLength":1},"genre":{"type":"string","maxLength":120},"bpmRange":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"],"additionalProperties":false}},"additionalProperties":false},"ambiencePreference":{"description":"Preferred ambience bed (`{ref}`) or explicit null (opt-out). Surfaced for driving agents; compose has no ambience auto-placement.","anyOf":[{"type":"object","properties":{"ref":{"type":"string","minLength":1}},"required":["ref"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"exemplarKeys":{"maxItems":24,"type":"array","items":{"type":"string","minLength":1}},"contactSheetKey":{"type":"string","minLength":1},"motifs":{"maxItems":24,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":40},"observed":{"type":"string","minLength":1,"maxLength":500},"body":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["kind","html"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["kind","primitiveId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["kind","componentId"],"additionalProperties":false}],"type":"object"},"motion":{"type":"object","properties":{"preset":{"type":"string","enum":["fade-up","slide-in-left","slide-in-right","scale-pop","stagger-reveal"]},"enterMs":{"type":"integer","minimum":0,"maximum":5000},"exitMs":{"type":"integer","minimum":0,"maximum":5000},"staggerMs":{"type":"integer","minimum":0,"maximum":2000},"confidence":{"type":"string","enum":["high","low"]}},"required":["preset"],"additionalProperties":false},"role":{"type":"string","enum":["title-card","stat","lower-third","pull-quote","hero","logo-tag","enumeration","sequence","comparison"]},"zone":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"w":{"type":"number"},"h":{"type":"number"}},"required":["x","y","w","h"],"additionalProperties":false},"evidence":{"maxItems":24,"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}},"diffScore":{"type":"number","minimum":0,"maximum":1},"coverage":{"type":"string","enum":["reproduced","approximated","skipped"]},"skipReason":{"type":"string","maxLength":300}},"required":["id","observed","body","role","coverage"],"additionalProperties":false}},"styleRubric":{"type":"string","maxLength":4000},"density":{"type":"object","properties":{"graphicsPerMin":{"type":"number","minimum":0,"maximum":60},"maxSimultaneous":{"type":"integer","minimum":1,"maximum":6}},"required":["graphicsPerMin","maxSimultaneous"],"additionalProperties":false},"inspiration":{"type":"object","properties":{"sources":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string"}},"extractedAt":{"type":"number"},"extractionVersion":{"type":"string","minLength":1,"maxLength":60}},"required":["sources","extractedAt","extractionVersion"],"additionalProperties":false},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","name","description","tagline","colors","fonts","voiceGuidelines","captions","createdAt","updatedAt"],"additionalProperties":false,"description":"Brand kit response per §Brand Kits."},"PaginationMeta":{"type":"object","properties":{"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]},"prevCursor":{"type":["string","null"]}},"required":["hasMore","nextCursor","prevCursor"],"additionalProperties":false,"description":"Cursor pagination metadata."},"BriefBeat":{"type":"object","properties":{"id":{"type":"string","minLength":1},"intent":{"type":"string","minLength":1,"description":"What this beat DOES editorially (hook the claim, prove it, CTA…)."},"durationSec":{"type":"number","exclusiveMinimum":0},"source":{"description":"MOMENT PINNING: this beat uses EXACTLY this window of this media item — honored to-the-frame or refused. v1: every sourced beat must reference the SAME mediaId (multi-source briefs are refused loudly, not silently merged).","type":"object","properties":{"mediaId":{"type":"string","minLength":1},"startSec":{"type":"number","minimum":0},"endSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","startSec","endSec"],"additionalProperties":false},"graphic":{"description":"GRAPHICS MANDATE: the plan MUST carry a graphics request of this role overlapping this beat's window — enforced at the plan gate (honor-or-refuse, like moment pinning). Prose mustIncludes reaches only the judge; this is the checkable form.","type":"object","properties":{"role":{"type":"string","enum":["title-card","stat","lower-third","pull-quote","hero","logo-tag","enumeration","sequence","comparison"],"description":"The mandated graphic's editorial role (the graphics-plan GraphicRole vocabulary)."},"items":{"description":"Mandated list items (enumeration/sequence) — carried VERBATIM into the plan's copy.items.","maxItems":8,"type":"array","items":{"type":"string","minLength":1,"maxLength":80}}},"required":["role"],"additionalProperties":false}},"required":["id","intent"],"additionalProperties":false},"BriefCreateRequest":{"type":"object","properties":{"projectId":{"type":"string","minLength":1},"name":{"type":"string","maxLength":200},"goal":{"type":"string","minLength":1,"maxLength":2000,"description":"What the video must accomplish."},"audience":{"type":"string","maxLength":500},"platform":{"type":"string","maxLength":100},"format":{"$ref":"#/components/schemas/FormatSpec"},"durationSec":{"description":"Target output duration. HONOR-OR-REFUSE: compose validates it against the beat-source window (±1.5s) and refuses a brief it cannot honor.","type":"number","exclusiveMinimum":0,"maximum":3600},"tone":{"type":"string","maxLength":500},"cta":{"type":"string","maxLength":500},"locale":{"description":"Output language (BCP-47 tag, e.g. 'es-419'): ALL on-screen copy + captions.","type":"string","maxLength":35},"hook":{"type":"string","maxLength":500},"caption":{"type":"string","maxLength":2000},"beats":{"maxItems":24,"type":"array","items":{"$ref":"#/components/schemas/BriefBeat"}},"mustIncludes":{"maxItems":24,"type":"array","items":{"type":"string","minLength":1}},"references":{"maxItems":12,"type":"array","items":{"type":"string"}},"captions":{"type":"object","properties":{"styleId":{"description":"Caption style id (e.g. 'serif-emphasis@1').","type":"string","minLength":1},"emphasisPhrases":{"description":"Phrases rendered in the caption EMPHASIS style (the big-serif treatment). Matched against the transcript; drives CaptionWord.emphasis.","maxItems":24,"type":"array","items":{"type":"string","minLength":1}}},"additionalProperties":false},"motionStyle":{"type":"object","properties":{"textAnimation":{"type":"string"},"transitions":{"type":"string"},"colorMood":{"type":"string"},"captionStyle":{"type":"string"}},"additionalProperties":false},"seededGraphics":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false},"description":"Client-authored graphic clips the Director must carry VERBATIM: seeded into the design loop's base composition as LOCKED clips (never re-authored, never discarded)."},"exclusions":{"maxItems":8,"type":"array","items":{"$ref":"#/components/schemas/BriefExclusion"}},"gates":{"$ref":"#/components/schemas/BriefGates"},"audio":{"$ref":"#/components/schemas/BriefAudio"}},"required":["projectId","goal"],"additionalProperties":false},"FormatSpec":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]}},"required":["aspectRatio"],"additionalProperties":false,"description":"Output-format spec per §Format."},"ComponentParameterValue":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"array","items":{"$ref":"#/components/schemas/ComponentParameterValue"}},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}}]},"BriefExclusion":{"type":"string","enum":["overlay","component","card","no-transitions"]},"BriefGates":{"type":"object","properties":{"holdAt":{"description":"Checkpoint gates — the compose pauses at each named stage for review via resume. DEFAULT (gates absent): the compose holds at EVERY stage — your agent reviews and resumes each one; an unreviewed checkpoint times out loudly after 60min. Auto-progression is the opt-in (gates.autoApprove: true).","maxItems":3,"type":"array","items":{"type":"string","enum":["content","layout","motion"]}},"autoApprove":{"description":"true = fully autonomous (compose runs with NO gates — the headless opt-in; without it a brief holds at every stage by default). Mutually exclusive with a non-empty holdAt.","type":"boolean"},"reviewMode":{"description":"Who captures the review decision. Default 'agent': you relay the packet and call resume. 'hosted': every checkpoint mints a review-page URL (checkpoint.ready payload + get_checkpoint's reviewUrl) where a human approves/revises from the browser — no account, no agent session; the recorded decision rides the SAME resume rail and you learn of it via checkpoint webhooks / wait_job.","type":"string","enum":["agent","hosted"]}},"additionalProperties":false},"BriefAudio":{"type":"object","properties":{"music":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the compose carries a music bed."},"mood":{"description":"Freeform mood/genre prompt for the GENERATED bed (e.g. 'understated editorial, warm'). Ignored when mediaId pins a track.","type":"string","maxLength":300},"mediaId":{"description":"Pin a client-imported track as the bed. HONOR-OR-REFUSE: must be an org-owned kind:'audio' media item, else 422 — never accept-and-ignore. Absent ⇒ generate from mood.","type":"string","minLength":1}},"required":["enabled"],"additionalProperties":false},"sfx":{"type":"object","properties":{"intensity":{"type":"string","enum":["off","light","standard","dense"],"description":"SFX placement density. Real-footage content keeps restraint caps regardless ('dense' is the explicit opt-out); generated/graphic-led content unlocks the standard tier."}},"required":["intensity"],"additionalProperties":false}},"additionalProperties":false},"BriefListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BriefResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"BriefResponse":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"kind":{"type":"string","enum":["authored","clip"],"description":"authored = create_brief; clip = minted by suggest_briefs from an AI clip suggestion."},"sourceSuggestionId":{"description":"kind:'clip' provenance — the suggestion this Brief was minted from.","type":"string"},"name":{"type":"string","maxLength":200},"goal":{"type":"string","minLength":1,"maxLength":2000,"description":"What the video must accomplish."},"audience":{"type":"string","maxLength":500},"platform":{"type":"string","maxLength":100},"format":{"$ref":"#/components/schemas/FormatSpec"},"durationSec":{"description":"Target output duration. HONOR-OR-REFUSE: compose validates it against the beat-source window (±1.5s) and refuses a brief it cannot honor.","type":"number","exclusiveMinimum":0,"maximum":3600},"tone":{"type":"string","maxLength":500},"cta":{"type":"string","maxLength":500},"locale":{"description":"Output language (BCP-47 tag, e.g. 'es-419'): ALL on-screen copy + captions.","type":"string","maxLength":35},"hook":{"type":"string","maxLength":500},"caption":{"type":"string","maxLength":2000},"beats":{"maxItems":24,"type":"array","items":{"$ref":"#/components/schemas/BriefBeat"}},"mustIncludes":{"maxItems":24,"type":"array","items":{"type":"string","minLength":1}},"references":{"maxItems":12,"type":"array","items":{"type":"string"}},"captions":{"type":"object","properties":{"styleId":{"description":"Caption style id (e.g. 'serif-emphasis@1').","type":"string","minLength":1},"emphasisPhrases":{"description":"Phrases rendered in the caption EMPHASIS style (the big-serif treatment). Matched against the transcript; drives CaptionWord.emphasis.","maxItems":24,"type":"array","items":{"type":"string","minLength":1}}},"additionalProperties":false},"motionStyle":{"type":"object","properties":{"textAnimation":{"type":"string"},"transitions":{"type":"string"},"colorMood":{"type":"string"},"captionStyle":{"type":"string"}},"additionalProperties":false},"seededGraphics":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false},"description":"Client-authored graphic clips the Director must carry VERBATIM: seeded into the design loop's base composition as LOCKED clips (never re-authored, never discarded)."},"exclusions":{"maxItems":8,"type":"array","items":{"$ref":"#/components/schemas/BriefExclusion"}},"gates":{"$ref":"#/components/schemas/BriefGates"},"audio":{"$ref":"#/components/schemas/BriefAudio"},"quote":{"$ref":"#/components/schemas/BriefQuote"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","projectId","kind","goal","quote","createdAt","updatedAt"],"additionalProperties":false},"BriefQuote":{"type":"object","properties":{"composeUsd":{"type":"number"},"renderUsdPerExport":{"type":"number"},"estimatedJourneyUsd":{"type":"number","description":"compose + expected renders — relay this BEFORE composing."},"revisionCyclesIncluded":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Revise cycles the compose price includes per gate (A1). Beyond this, resume(revise) is refused with `revision_cycles_exhausted` — saying no never silently charges."}},"required":["composeUsd","renderUsdPerExport","estimatedJourneyUsd","revisionCyclesIncluded"],"additionalProperties":false},"BriefPatchRequest":{"type":"object","properties":{"name":{"type":"string","maxLength":200},"goal":{"type":"string","minLength":1,"maxLength":2000,"description":"What the video must accomplish."},"audience":{"type":"string","maxLength":500},"platform":{"type":"string","maxLength":100},"format":{"$ref":"#/components/schemas/FormatSpec"},"durationSec":{"description":"Target output duration. HONOR-OR-REFUSE: compose validates it against the beat-source window (±1.5s) and refuses a brief it cannot honor.","type":"number","exclusiveMinimum":0,"maximum":3600},"tone":{"type":"string","maxLength":500},"cta":{"type":"string","maxLength":500},"locale":{"description":"Output language (BCP-47 tag, e.g. 'es-419'): ALL on-screen copy + captions.","type":"string","maxLength":35},"hook":{"type":"string","maxLength":500},"caption":{"type":"string","maxLength":2000},"beats":{"maxItems":24,"type":"array","items":{"$ref":"#/components/schemas/BriefBeat"}},"mustIncludes":{"maxItems":24,"type":"array","items":{"type":"string","minLength":1}},"references":{"maxItems":12,"type":"array","items":{"type":"string"}},"captions":{"type":"object","properties":{"styleId":{"description":"Caption style id (e.g. 'serif-emphasis@1').","type":"string","minLength":1},"emphasisPhrases":{"description":"Phrases rendered in the caption EMPHASIS style (the big-serif treatment). Matched against the transcript; drives CaptionWord.emphasis.","maxItems":24,"type":"array","items":{"type":"string","minLength":1}}},"additionalProperties":false},"motionStyle":{"type":"object","properties":{"textAnimation":{"type":"string"},"transitions":{"type":"string"},"colorMood":{"type":"string"},"captionStyle":{"type":"string"}},"additionalProperties":false},"seededGraphics":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false},"description":"Client-authored graphic clips the Director must carry VERBATIM: seeded into the design loop's base composition as LOCKED clips (never re-authored, never discarded)."},"exclusions":{"maxItems":8,"type":"array","items":{"$ref":"#/components/schemas/BriefExclusion"}},"gates":{"$ref":"#/components/schemas/BriefGates"},"audio":{"$ref":"#/components/schemas/BriefAudio"}},"additionalProperties":false},"CheckoutRequest":{"type":"object","properties":{"plan":{"type":"string","enum":["credit_pack_10","credit_pack_30","credit_pack_100"],"description":"Plan tier to subscribe to."},"interval":{"default":"month","description":"Billing interval: 'month' (monthly) or 'year' (annual, ~2 months free).","type":"string","enum":["month","year"]}},"required":["plan","interval"],"additionalProperties":false},"CheckoutResponse":{"type":"object","properties":{"url":{"type":"string","description":"Hosted Stripe checkout URL to open in a browser to complete payment. Always present on success — an existing saved card is never charged without confirming here."},"plan":{"type":"string"},"interval":{"type":"string"},"productId":{"type":"string","description":"Resolved billing catalog product id."}},"required":["url","plan","interval","productId"],"additionalProperties":false},"CheckpointComment":{"type":"object","properties":{"anchor":{"anyOf":[{"type":"object","properties":{"beatId":{"type":"string","minLength":1}},"required":["beatId"],"additionalProperties":false},{"type":"object","properties":{"timecodeMs":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["timecodeMs"],"additionalProperties":false}],"description":"What the comment is about: a plan beat (content gate) or a timecode on the artifact (layout/motion gates)."},"verdict":{"type":"string","enum":["approve","revise","lock"],"description":"Per-anchor verdict under the single gate decision. `lock` = contractually frozen — the director touching a locked element is a defect, surfaced as a lock_violation verdict on the next packet (the no-discard machinery)."},"note":{"type":"string","maxLength":2000}},"required":["anchor","verdict"],"additionalProperties":false},"CheckpointListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CheckpointResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"CheckpointResponse":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"composeJobId":{"type":"string"},"briefId":{"type":"string"},"kind":{"type":"string","enum":["gate","score"]},"stage":{"$ref":"#/components/schemas/CheckpointStage"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["awaiting","approved","revised","abandoned","expired","superseded"]},"artifact":{"description":"The stage artifact under review: the locked ComposePlan at content; the composition wire shape at layout/motion; the judged composition snapshot on kind:'score'."},"stillUrls":{"description":"Presigned storyboard/eval stills — the packet's visual evidence (may be GC'd by the retention sweep after the job goes terminal; the decision record is immortal).","type":"array","items":{"type":"string"}},"criticVerdicts":{"description":"Per-criterion scores + critique from the design loop / judge, incl. lock_violation entries."},"quote":{"$ref":"#/components/schemas/CheckpointQuote"},"revisionCycle":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Revise cycles this gate has consumed. The brief quote states the included count (revisionCyclesIncluded); beyond it, resume(revise) is refused with a typed error."},"decision":{"description":"The recorded decision {decision, comments?, globalNote?, decidedAt} once resolved."},"reviewMode":{"description":"How this packet is decided (from the Brief's gates). 'hosted' = the review PAGE captures the decision; absent/'agent' = the decision flows back through the driving agent.","type":"string","enum":["agent","hosted"]},"reviewUrl":{"description":"Hosted review-page URL (present when reviewMode is 'hosted') — a human decides from this link, no account or agent session; the recorded decision rides the SAME resume rail, and the agent learns of it via checkpoint webhooks / wait_job.","type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","projectId","kind","version","status","artifact","revisionCycle","createdAt","updatedAt"],"additionalProperties":false},"CheckpointStage":{"type":"string","enum":["content","layout","motion"]},"CheckpointQuote":{"type":"object","properties":{"thisStepUsd":{"type":"number","description":"What approving costs NEXT (the render at the final gate; $0 earlier)."},"jobSpendSoFarUsd":{"type":"number","description":"What has SETTLED so far — $0 while the run is live (compose is charge-on-delivery on both rails), so abandoning at a gate charges nothing."},"estimatedJourneyTotalUsd":{"type":"number","description":"The same journey number the Brief quoted."}},"required":["thisStepUsd","jobSpendSoFarUsd","estimatedJourneyTotalUsd"],"additionalProperties":false},"CheckpointResumeRequest":{"type":"object","properties":{"decision":{"type":"string","enum":["approve","revise","abandon"],"description":"The ONE verdict for this gate (GitHub review grammar). approve = proceed (comments allowed — they record as taste signal without gating); revise = the director revises per comments/edits and RE-PRESENTS this same gate (in-job, no re-meter); abandon = end the run."},"comments":{"maxItems":24,"type":"array","items":{"$ref":"#/components/schemas/CheckpointComment"}},"edits":{"description":"Your edited stage artifact (the power path). With edits the re-presented packet carries exactly what you supplied; with comments alone the director re-authors scoped by them."},"globalNote":{"type":"string","maxLength":4000}},"required":["decision"],"additionalProperties":false,"description":"POST /checkpoints/:id/resume body — the A1 review grammar.","example":{"decision":"approve"}},"CheckpointResumeResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true}},"required":["ok"],"additionalProperties":false,"description":"POST /checkpoints/:id/resume response."},"ComponentCreateRequest":{"type":"object","properties":{"componentId":{"type":"string","minLength":1,"maxLength":200,"description":"Caller-chosen stable component id. On create it names the new component. On PUT/PATCH it is optional and, when present, must equal the id in the path; a mismatch is a 400 naming both."},"tsxSource":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"$ref":"#/components/schemas/ComponentManifestV2"},"source":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":2},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-z0-9][a-z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1,"maxLength":8000000},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false},"definition":{"type":"object","properties":{"inputSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"defaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"brandBindings":{"type":"array","items":{"type":"object","properties":{"propPath":{"type":"string","minLength":1,"maxLength":128},"cssVar":{"type":"string","minLength":1,"maxLength":128},"fallback":{"type":"string"},"brandKitPath":{"type":"string","minLength":1,"maxLength":128}},"required":["propPath","cssVar"],"additionalProperties":false}},"timing":{"type":"object","properties":{"defaultDuration":{"type":"object","properties":{"frames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0}},"required":["frames","fps"],"additionalProperties":false},"minDurationSec":{"type":"number","exclusiveMinimum":0},"maxDurationSec":{"type":"number","exclusiveMinimum":0}},"required":["defaultDuration"],"additionalProperties":false},"capabilities":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"clip"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cut-transition"},"protocol":{"type":"string","const":"per-child"}},"required":["kind","protocol"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"content-slots"},"slots":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ownership":{"type":"string","enum":["reference","exclusive"]},"sizing":{"type":"string","enum":["canvas","container"]}},"required":["name","min","max","ownership","sizing"],"additionalProperties":false}}},"required":["kind","slots"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"clip-wrapper"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","ordering","acceptsWrappedTargets"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"global-wrapper"},"scope":{"type":"string","const":"media-lanes"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","scope","ordering","acceptsWrappedTargets"],"additionalProperties":false}],"type":"object"}},"mediaBindings":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"propPath":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"string","minLength":1,"maxLength":128}},"kind":{"type":"string","enum":["image","video","visual"]},"collection":{"type":"string","enum":["scalar","array"]},"cardinality":{"type":"object","properties":{"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["min"],"additionalProperties":false},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["name","propPath","kind","collection","cardinality"],"additionalProperties":false}},"preview":{"type":"object","properties":{"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}}}},"additionalProperties":false}},"required":["inputSchema","defaults","brandBindings","timing","capabilities"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest","definition"],"additionalProperties":false}]},"supportedSourceVersions":{"minItems":1,"maxItems":2,"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}}},"required":["componentId","name","description","category"],"additionalProperties":false,"description":"POST /components body. Org/user are server-resolved; never accepted from the body."},"ComponentManifestV2":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false},"ComponentListResponse":{"anyOf":[{"$ref":"#/components/schemas/LegacyComponentListResponse"},{"type":"object","properties":{"protocolVersion":{"type":"number","const":1},"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"data":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"identity":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"id":{"type":"string","minLength":1,"maxLength":256},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["scope","id","revision"],"additionalProperties":false},"name":{"type":"string","minLength":1,"maxLength":256},"description":{"type":"string"},"category":{"type":"string","minLength":1,"maxLength":256},"presentation":{"type":"object","properties":{"version":{"type":"number","const":1},"representativeTimeSeconds":{"type":"number","minimum":0}},"required":["version","representativeTimeSeconds"],"additionalProperties":false},"showcase":{"type":"object","properties":{"version":{"type":"number","const":1},"presentationKey":{"type":"string","minLength":1},"fixtureIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"rendererIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"video":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0},"durationInFrames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","width","height","fps","durationInFrames"],"additionalProperties":false},"poster":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"frame":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","frame"],"additionalProperties":false}},"required":["version","presentationKey","fixtureIdentity","rendererIdentity","video","poster"],"additionalProperties":false},"preview":{"type":"object","properties":{"identity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"status":{"type":"string","enum":["unproven","verified"]}},"required":["identity","status"],"additionalProperties":false},"kind":{"type":"string","const":"definition"},"source":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceVersion":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}},"required":["scope","componentId","sourceVersionId","sourceVersion"],"additionalProperties":false},"declaration":{"oneOf":[{"type":"object","properties":{"state":{"type":"string","const":"v3"},"capabilities":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"clip"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cut-transition"},"protocol":{"type":"string","const":"per-child"}},"required":["kind","protocol"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"content-slots"},"slots":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ownership":{"type":"string","enum":["reference","exclusive"]},"sizing":{"type":"string","enum":["canvas","container"]}},"required":["name","min","max","ownership","sizing"],"additionalProperties":false}}},"required":["kind","slots"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"clip-wrapper"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","ordering","acceptsWrappedTargets"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"global-wrapper"},"scope":{"type":"string","const":"media-lanes"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","scope","ordering","acceptsWrappedTargets"],"additionalProperties":false}],"type":"object"}},"timing":{"type":"object","properties":{"defaultDuration":{"type":"object","properties":{"frames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0}},"required":["frames","fps"],"additionalProperties":false},"minDurationSec":{"type":"number","exclusiveMinimum":0},"maxDurationSec":{"type":"number","exclusiveMinimum":0}},"required":["defaultDuration"],"additionalProperties":false}},"required":["state","capabilities","timing"],"additionalProperties":false},{"type":"object","properties":{"state":{"type":"string","const":"legacy-v2"},"metadataStatus":{"type":"string","const":"unresolved"}},"required":["state","metadataStatus"],"additionalProperties":false}],"type":"object"},"origin":{"type":"string","enum":["server-native","customer-owned"]}},"required":["identity","name","description","category","kind","source","declaration","origin"],"additionalProperties":false},{"type":"object","properties":{"identity":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"id":{"type":"string","minLength":1,"maxLength":256},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["scope","id","revision"],"additionalProperties":false},"name":{"type":"string","minLength":1,"maxLength":256},"description":{"type":"string"},"category":{"type":"string","minLength":1,"maxLength":256},"presentation":{"type":"object","properties":{"version":{"type":"number","const":1},"representativeTimeSeconds":{"type":"number","minimum":0}},"required":["version","representativeTimeSeconds"],"additionalProperties":false},"showcase":{"type":"object","properties":{"version":{"type":"number","const":1},"presentationKey":{"type":"string","minLength":1},"fixtureIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"rendererIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"video":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0},"durationInFrames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","width","height","fps","durationInFrames"],"additionalProperties":false},"poster":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"frame":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","frame"],"additionalProperties":false}},"required":["version","presentationKey","fixtureIdentity","rendererIdentity","video","poster"],"additionalProperties":false},"preview":{"type":"object","properties":{"identity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"status":{"type":"string","enum":["unproven","verified"]}},"required":["identity","status"],"additionalProperties":false},"kind":{"type":"string","const":"preset"},"definition":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceVersion":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}},"required":["scope","componentId","sourceVersionId","sourceVersion"],"additionalProperties":false},"presetVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"historicalDocument":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"documentId":{"type":"string","minLength":1,"maxLength":256},"documentSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["scope","documentId","documentSha256"],"additionalProperties":false},"equivalence":{"type":"string","enum":["unproven","verified"]}},"required":["identity","name","description","category","kind","definition","presetVersionId","historicalDocument","equivalence"],"additionalProperties":false},{"type":"object","properties":{"identity":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"id":{"type":"string","minLength":1,"maxLength":256},"revision":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["scope","id","revision"],"additionalProperties":false},"name":{"type":"string","minLength":1,"maxLength":256},"description":{"type":"string"},"category":{"type":"string","minLength":1,"maxLength":256},"presentation":{"type":"object","properties":{"version":{"type":"number","const":1},"representativeTimeSeconds":{"type":"number","minimum":0}},"required":["version","representativeTimeSeconds"],"additionalProperties":false},"showcase":{"type":"object","properties":{"version":{"type":"number","const":1},"presentationKey":{"type":"string","minLength":1},"fixtureIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"rendererIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"video":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0},"durationInFrames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","width","height","fps","durationInFrames"],"additionalProperties":false},"poster":{"type":"object","properties":{"file":{"type":"string","minLength":1},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteLength":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"frame":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["file","sha256","byteLength","frame"],"additionalProperties":false}},"required":["version","presentationKey","fixtureIdentity","rendererIdentity","video","poster"],"additionalProperties":false},"preview":{"type":"object","properties":{"identity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"status":{"type":"string","enum":["unproven","verified"]}},"required":["identity","status"],"additionalProperties":false},"kind":{"type":"string","const":"recipe"},"document":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"documentId":{"type":"string","minLength":1,"maxLength":256},"documentSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["scope","documentId","documentSha256"],"additionalProperties":false},"placementCount":{"type":"integer","minimum":1,"maximum":9007199254740991},"memberSources":{"minItems":1,"type":"array","items":{"type":"object","properties":{"scope":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-local"},"orgId":{"type":"string","minLength":1,"maxLength":256},"workspaceId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","workspaceId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"org-hosted"},"orgId":{"type":"string","minLength":1,"maxLength":256},"deploymentId":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","orgId","deploymentId"],"additionalProperties":false}],"type":"object"},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceVersion":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}},"required":["scope","componentId","sourceVersionId","sourceVersion"],"additionalProperties":false}},"equivalence":{"type":"string","enum":["unproven","verified"]}},"required":["identity","name","description","category","kind","document","placementCount","memberSources","equivalence"],"additionalProperties":false}],"type":"object"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["protocolVersion","data","pagination"],"additionalProperties":false}]},"LegacyComponentListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ComponentResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"},"brandTokens":{"description":"Catalog-level reference: the valid `$brand:` token refs a param value may carry (e.g. accentColor: \"$brand:colors.accent\"). Colors + fonts are the common bindings; the full design-token vocabulary is listed. Derived from the brand kit resolver so it can't drift. See each entry's `brandBindings` for which params are brand-bound by default.","type":"array","items":{"type":"string"}},"sfx":{"description":"Catalog-level reference: the curated CC0 SFX pack (closed, versioned). The compose sfx pass places these deterministically; this is the pack-only structural inventory to pick a `soundId` by family. Present on the first page only.","type":"array","items":{"$ref":"#/components/schemas/SfxCatalogEntry"}},"audio":{"description":"The UNIFIED org sound palette (audio-substrate Phase 2): the curated packs (SFX + music beds) unioned with THIS org's own uploads/imports (source:\"org\") and generated audio (source:\"generated\"), one uniform entry shape carrying role + envelopeClass + provenance + license; music entries carry bpm. Prefer an org sound when it fits — an org that uploads its product's real UI sounds hears ITS product. Present on the first page only.","type":"array","items":{"$ref":"#/components/schemas/AudioPaletteEntry"}}},"required":["data","pagination"],"additionalProperties":false},"ComponentResponse":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"description":"The stored runtime manifest (assets, graphics API, alpha policy) of an org-INSTALLED component: the same object the create/update body takes, so a manifest read back here can be written back unchanged. Built-in defaults have no stored manifest and omit it. Its `version` is always 2 (the contract version), unlike the entry's semver `version`.","$ref":"#/components/schemas/ComponentManifestV2"},"id":{"type":"string","description":"The entry's id: a `primitiveId` for a built-in, a `componentId` for an installed component."},"source":{"type":"string","enum":["default","installed"],"description":"'default' = built-in primitive (place by primitiveId); 'installed' = org-authored component (place by componentId)."},"kind":{"type":"string","enum":["component","transition","scene"],"description":"RENDER kind (component | transition | scene). NOT the ClipSource variant — see `placement` for how to author it on the timeline."},"version":{"type":"string","description":"The ENTRY's version: a semver string ('0.0.0' until an authored component is versioned). Distinct from `manifest.version`, which is the runtime contract version and is always the literal 2."},"propDefaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"textParam":{"description":"The param field that carries this primitive's primary text; null = no single text slot.","type":["string","null"]},"subtextParam":{"description":"The param field for secondary text (subtitle/byline); null = none.","type":["string","null"]},"format":{"$ref":"#/components/schemas/SceneFormat"},"intent":{"description":"Selection signal: a verb naming what this primitive accomplishes (e.g. 'product-trailer'). Match it to the beat you are authoring.","type":"string"},"useWhen":{"description":"When to use this — AND when not to. The negative guidance is load-bearing; read it before picking.","type":"string"},"pairsWith":{"description":"Authoring guidance: ids of primitives that COMPOSE well with this one in the same edit.","type":"array","items":{"type":"string"}},"avoidWith":{"description":"Authoring guidance: ids of primitives that CONFLICT with this one — do not place together.","type":"array","items":{"type":"string"}},"tags":{"description":"Free-text search keywords.","type":"array","items":{"type":"string"}},"mood":{"description":"Vibe/tone tags (e.g. 'cinematic', 'minimal'). Filter to match the edit's mood.","type":"array","items":{"type":"string"}},"tier":{"description":"Quality/applicability RANKING (a preference, not a flag). Prefer 'recommended'; reach for 'niche' only when its specific use-case is exactly the beat.","type":"string","enum":["recommended","standard","niche"]},"useCase":{"description":"The edit ROLE(s) this primitive fills — the dimension to filter by for a beat (e.g. 'intro', 'title-over-footage', 'grade').","type":"array","items":{"type":"string","enum":["intro","outro","full-scene","title-over-footage","transition","background","grade","emphasis","explainer","social-cut"]}},"fixedCopy":{"description":"On-screen strings this primitive BAKES — the read-side counterpart to propSchema. These literals render REGARDLESS of params (no param can change them); fork the source via get_component_source to edit them. Use this to see at author time what fixed copy (someone-else's marketing text, faux-code, faux-data) will appear before you render.","type":"array","items":{"type":"string"}},"brandBindings":{"description":"Params that can follow the project brand kit. Each {param, brandToken} says: set `param` to `brandToken` (a `$brand:` ref, e.g. '$brand:colors.accent') to track the brand instead of a literal. See the list response's `brandTokens` for the full ref vocabulary. Omitted when nothing is brand-bound.","type":"array","items":{"type":"object","properties":{"param":{"type":"string"},"brandToken":{"type":"string"}},"required":["param","brandToken"],"additionalProperties":false}},"placement":{"description":"How to author this entry as a ClipSource via apply_composition: the exact ClipSource `kind` + the id field to key it by. Built-ins place as {kind:'overlay'|'effect', primitiveId}; installed components place as {kind:'component', componentId}. A kind:'scene' primitive has no 'scene' ClipSource — it is placed as {kind:'overlay', primitiveId}.","$ref":"#/components/schemas/ComponentPlacement"},"warnings":{"description":"Non-blocking save-time advisories — the create/update SUCCEEDED. Currently: a `fontFamily` string literal referencing a NON-vendored font (a bare CSS generic like 'serif', or an unknown named family like 'Arial') whose LIVE-lane pixels vary by render host — re-author with a vendored family or 'Georgia'. Omitted when there is nothing to flag; only present on the create/update responses.","type":"array","items":{"type":"string"}}},"required":["name","description","category","propSchema","id","source","kind","version","placement"],"additionalProperties":false,"description":"Component catalog entry per §Components."},"SceneFormat":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]}},"required":["aspectRatio"],"additionalProperties":false},"ComponentPlacement":{"type":"object","properties":{"clipSourceKind":{"type":"string","enum":["overlay","effect","component"],"description":"The ClipSource `kind` to author this entry as: 'overlay' (built-in text/ui/scene/background/layout), 'effect' (built-in effect/transition), or 'component' (an org-INSTALLED custom component)."},"refField":{"type":"string","enum":["primitiveId","componentId"],"description":"Which id field keys the ClipSource: 'primitiveId' for built-ins (source:'default'), 'componentId' for installed components (source:'installed'). Using the wrong field will NOT resolve at render."}},"required":["clipSourceKind","refField"],"additionalProperties":false},"SfxCatalogEntry":{"type":"object","properties":{"soundId":{"type":"string","description":"Stable sound-pack item id."},"family":{"type":"string","enum":["tick","pop","impact","confirm","error","whoosh","riser"],"description":"Editorial family the compose sfx pass binds by."},"envelopeClass":{"type":"string","enum":["transient","sweep","ambient"],"description":"Coarse envelope shape — the browse grouping."},"intensity":{"type":"string","enum":["subtle","standard","strong"]},"durationSec":{"type":"number","description":"Duration of the mastered asset (seconds)."},"description":{"type":"string","description":"One-line human-legible caption."},"attribution":{"type":"string","description":"CC0 provenance string."}},"required":["soundId","family","envelopeClass","intensity","durationSec","description","attribution"],"additionalProperties":false},"ComponentPatchRequest":{"type":"object","properties":{"componentId":{"type":"string","minLength":1,"maxLength":200,"description":"Caller-chosen stable component id. On create it names the new component. On PUT/PATCH it is optional and, when present, must equal the id in the path; a mismatch is a 400 naming both."},"tsxSource":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"$ref":"#/components/schemas/ComponentManifestV2"},"source":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":2},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-z0-9][a-z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1,"maxLength":8000000},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false},"definition":{"type":"object","properties":{"inputSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"defaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"brandBindings":{"type":"array","items":{"type":"object","properties":{"propPath":{"type":"string","minLength":1,"maxLength":128},"cssVar":{"type":"string","minLength":1,"maxLength":128},"fallback":{"type":"string"},"brandKitPath":{"type":"string","minLength":1,"maxLength":128}},"required":["propPath","cssVar"],"additionalProperties":false}},"timing":{"type":"object","properties":{"defaultDuration":{"type":"object","properties":{"frames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0}},"required":["frames","fps"],"additionalProperties":false},"minDurationSec":{"type":"number","exclusiveMinimum":0},"maxDurationSec":{"type":"number","exclusiveMinimum":0}},"required":["defaultDuration"],"additionalProperties":false},"capabilities":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"clip"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cut-transition"},"protocol":{"type":"string","const":"per-child"}},"required":["kind","protocol"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"content-slots"},"slots":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ownership":{"type":"string","enum":["reference","exclusive"]},"sizing":{"type":"string","enum":["canvas","container"]}},"required":["name","min","max","ownership","sizing"],"additionalProperties":false}}},"required":["kind","slots"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"clip-wrapper"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","ordering","acceptsWrappedTargets"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"global-wrapper"},"scope":{"type":"string","const":"media-lanes"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","scope","ordering","acceptsWrappedTargets"],"additionalProperties":false}],"type":"object"}},"mediaBindings":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"propPath":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"string","minLength":1,"maxLength":128}},"kind":{"type":"string","enum":["image","video","visual"]},"collection":{"type":"string","enum":["scalar","array"]},"cardinality":{"type":"object","properties":{"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["min"],"additionalProperties":false},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["name","propPath","kind","collection","cardinality"],"additionalProperties":false}},"preview":{"type":"object","properties":{"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}}}},"additionalProperties":false}},"required":["inputSchema","defaults","brandBindings","timing","capabilities"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest","definition"],"additionalProperties":false}]},"supportedSourceVersions":{"minItems":1,"maxItems":2,"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}},"projectId":{"description":"A project whose explicitly named composition moves its placements atomically with the source write. Requires compositionId and concurrency.","type":"string","minLength":1},"compositionId":{"description":"The exact composition observed by the caller. Required with projectId and concurrency.","type":"string","minLength":1},"concurrency":{"description":"Caller-observed placement guard. component.repin currently requires mode:exact; guarded mode refuses before writes.","$ref":"#/components/schemas/CompositionConcurrency"}},"additionalProperties":false,"description":"PATCH /components/:id body, RFC 7396 merge: a field you omit is left exactly as it was. Org/user are server-resolved; never accepted from the body.","examples":[{"name":"Renamed title"}]},"CompositionConcurrency":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"exact"},"expectedRevision":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["mode","expectedRevision"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"guarded"},"compositionId":{"type":"string","minLength":1,"maxLength":128},"observedRevision":{"type":"integer","minimum":0,"maximum":9007199254740991},"basis":{"maxItems":2048,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":256},"token":{"type":"string","maxLength":65536}},"required":["key","token"],"additionalProperties":false}}},"required":["mode","observedRevision","basis"],"additionalProperties":false}],"type":"object"},"ComponentPreviewImageResult":{"type":"object","properties":{"artifactKind":{"type":"string","const":"image"},"contentType":{"type":"string","enum":["image/png","image/jpeg"]},"cached":{"type":"boolean"},"listUsd":{"description":"List price charged for this delivered preview.","type":"number"},"url":{"type":"string","format":"uri"},"urlExpiresAt":{"type":"string"}},"required":["artifactKind","contentType","cached","url","urlExpiresAt"],"additionalProperties":false},"ComponentPreviewJobResult":{"anyOf":[{"$ref":"#/components/schemas/ComponentPreviewImageResult"},{"$ref":"#/components/schemas/ComponentPreviewMotionResult"}]},"ComponentPreviewMotionResult":{"type":"object","properties":{"artifactKind":{"type":"string","const":"motion"},"contentType":{"type":"string","const":"video/webm"},"cached":{"type":"boolean"},"listUsd":{"description":"List price charged for this delivered preview.","type":"number"},"url":{"type":"string","format":"uri"},"urlExpiresAt":{"type":"string"}},"required":["artifactKind","contentType","cached","url","urlExpiresAt"],"additionalProperties":false},"ComponentPreviewRequest":{"type":"object","properties":{"componentId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Component asset-slot name to org mediaId. Every required manifest slot must be bound.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"description":"Preview frame rate. When omitted, uses the project's format.","type":"number","exclusiveMinimum":0,"maximum":120},"durationInFrames":{"description":"Preview frame count. When omitted, uses the component's declared duration; required if the component has none.","type":"integer","minimum":1,"maximum":3600}},"required":["componentId"],"additionalProperties":false,"example":{"componentId":"cmp_lower_third","params":{"title":"Q3 revenue","subtitle":"up 40%"}}},"ComponentSourceResponse":{"type":"object","properties":{"tsxSource":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"$ref":"#/components/schemas/ComponentManifestV2"},"id":{"type":"string"},"source":{"type":"string","enum":["default","installed"]},"metadataStatus":{"description":"Historical source-only reads omit unavailable discovery name/description instead of borrowing current metadata.","type":"string","const":"unresolved"},"sourceVersionId":{"description":"Exact immutable source pin, returned beside an opted-in sourceSnapshot; distinct from bundle revisions.","type":"string"},"sourceSnapshot":{"description":"Canonical immutable source snapshot, returned on explicit supportedSourceVersions opt-in; source remains provenance.","anyOf":[{"type":"object","properties":{"version":{"type":"number","const":2},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-z0-9][a-z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1,"maxLength":8000000},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false},"definition":{"type":"object","properties":{"inputSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"defaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"brandBindings":{"type":"array","items":{"type":"object","properties":{"propPath":{"type":"string","minLength":1,"maxLength":128},"cssVar":{"type":"string","minLength":1,"maxLength":128},"fallback":{"type":"string"},"brandKitPath":{"type":"string","minLength":1,"maxLength":128}},"required":["propPath","cssVar"],"additionalProperties":false}},"timing":{"type":"object","properties":{"defaultDuration":{"type":"object","properties":{"frames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0}},"required":["frames","fps"],"additionalProperties":false},"minDurationSec":{"type":"number","exclusiveMinimum":0},"maxDurationSec":{"type":"number","exclusiveMinimum":0}},"required":["defaultDuration"],"additionalProperties":false},"capabilities":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"clip"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cut-transition"},"protocol":{"type":"string","const":"per-child"}},"required":["kind","protocol"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"content-slots"},"slots":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ownership":{"type":"string","enum":["reference","exclusive"]},"sizing":{"type":"string","enum":["canvas","container"]}},"required":["name","min","max","ownership","sizing"],"additionalProperties":false}}},"required":["kind","slots"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"clip-wrapper"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","ordering","acceptsWrappedTargets"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"global-wrapper"},"scope":{"type":"string","const":"media-lanes"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","scope","ordering","acceptsWrappedTargets"],"additionalProperties":false}],"type":"object"}},"mediaBindings":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"propPath":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"string","minLength":1,"maxLength":128}},"kind":{"type":"string","enum":["image","video","visual"]},"collection":{"type":"string","enum":["scalar","array"]},"cardinality":{"type":"object","properties":{"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["min"],"additionalProperties":false},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["name","propPath","kind","collection","cardinality"],"additionalProperties":false}},"preview":{"type":"object","properties":{"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}}}},"additionalProperties":false}},"required":["inputSchema","defaults","brandBindings","timing","capabilities"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest","definition"],"additionalProperties":false}]}},"required":["tsxSource","propSchema","manifest","id","source"],"additionalProperties":false,"description":"Installed component SOURCE (TSX) + ownership provenance per §Components."},"ComponentUpdateRequest":{"type":"object","properties":{"componentId":{"type":"string","minLength":1,"maxLength":200,"description":"Caller-chosen stable component id. On create it names the new component. On PUT/PATCH it is optional and, when present, must equal the id in the path; a mismatch is a 400 naming both."},"tsxSource":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"$ref":"#/components/schemas/ComponentManifestV2"},"source":{"anyOf":[{"type":"object","properties":{"version":{"type":"number","const":2},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-z0-9][a-z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9._-]*$"},"tsxSource":{"type":"string","minLength":1,"maxLength":8000000},"manifest":{"type":"object","properties":{"version":{"type":"number","const":2},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"kind":{"type":"string","enum":["image","video","audio","data","visual"]},"required":{"type":"boolean"},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["kind","required"],"additionalProperties":false}},"graphics":{"type":"object","properties":{"api":{"type":"string","enum":["canvas2d","webgl","webgl2","webgpu"]},"required":{"type":"boolean","const":true},"accelerationPreference":{"type":"string","enum":["hardware-preferred","software-allowed"]}},"required":["api","required","accelerationPreference"],"additionalProperties":false},"alphaPolicy":{"type":"string","enum":["requires-transparency","allows-opaque"]},"sceneShot":{"type":"object","properties":{"version":{"type":"number","const":2}},"required":["version"],"additionalProperties":false},"visualMedia":{"type":"object","properties":{"version":{"type":"number","const":1}},"required":["version"],"additionalProperties":false}},"required":["version","assets","graphics","alphaPolicy"],"additionalProperties":false},"definition":{"type":"object","properties":{"inputSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"defaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"brandBindings":{"type":"array","items":{"type":"object","properties":{"propPath":{"type":"string","minLength":1,"maxLength":128},"cssVar":{"type":"string","minLength":1,"maxLength":128},"fallback":{"type":"string"},"brandKitPath":{"type":"string","minLength":1,"maxLength":128}},"required":["propPath","cssVar"],"additionalProperties":false}},"timing":{"type":"object","properties":{"defaultDuration":{"type":"object","properties":{"frames":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fps":{"type":"number","exclusiveMinimum":0}},"required":["frames","fps"],"additionalProperties":false},"minDurationSec":{"type":"number","exclusiveMinimum":0},"maxDurationSec":{"type":"number","exclusiveMinimum":0}},"required":["defaultDuration"],"additionalProperties":false},"capabilities":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"clip"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"cut-transition"},"protocol":{"type":"string","const":"per-child"}},"required":["kind","protocol"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"content-slots"},"slots":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"ownership":{"type":"string","enum":["reference","exclusive"]},"sizing":{"type":"string","enum":["canvas","container"]}},"required":["name","min","max","ownership","sizing"],"additionalProperties":false}}},"required":["kind","slots"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"clip-wrapper"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","ordering","acceptsWrappedTargets"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"global-wrapper"},"scope":{"type":"string","const":"media-lanes"},"ordering":{"type":"string","enum":["any","innermost"]},"acceptsWrappedTargets":{"type":"boolean"}},"required":["kind","scope","ordering","acceptsWrappedTargets"],"additionalProperties":false}],"type":"object"}},"mediaBindings":{"minItems":1,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"propPath":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"string","minLength":1,"maxLength":128}},"kind":{"type":"string","enum":["image","video","visual"]},"collection":{"type":"string","enum":["scalar","array"]},"cardinality":{"type":"object","properties":{"min":{"type":"integer","minimum":0,"maximum":9007199254740991},"max":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["min"],"additionalProperties":false},"mimeTypes":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"mediaDemand":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"original"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"tier"},"tier":{"anyOf":[{"type":"number","const":256},{"type":"number","const":512},{"type":"number","const":1024},{"type":"number","const":2048}]}},"required":["mode","tier"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"auto"},"maxProjectedWidthRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"maxProjectedHeightRatio":{"type":"number","exclusiveMinimum":0,"maximum":64},"minVisibleSourceWidthRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1},"minVisibleSourceHeightRatio":{"default":1,"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["mode","maxProjectedWidthRatio","maxProjectedHeightRatio","minVisibleSourceWidthRatio","minVisibleSourceHeightRatio"],"additionalProperties":false}],"type":"object"}},"required":["name","propPath","kind","collection","cardinality"],"additionalProperties":false}},"preview":{"type":"object","properties":{"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["url","sha256","mimeType"],"additionalProperties":false},{"type":"object","properties":{"mediaId":{"type":"string","minLength":1,"maxLength":128},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mimeType":{"type":"string","minLength":1},"frameRate":{"type":"number","exclusiveMinimum":0},"durationSec":{"type":"number","exclusiveMinimum":0}},"required":["mediaId","sha256","mimeType"],"additionalProperties":false}]}}}},"additionalProperties":false}},"required":["inputSchema","defaults","brandBindings","timing","capabilities"],"additionalProperties":false}},"required":["version","componentId","tsxSource","manifest","definition"],"additionalProperties":false}]},"supportedSourceVersions":{"minItems":1,"maxItems":2,"type":"array","items":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}]}},"projectId":{"description":"A project whose explicitly named composition moves its placements atomically with the source write. Requires compositionId and concurrency.","type":"string","minLength":1},"compositionId":{"description":"The exact composition observed by the caller. Required with projectId and concurrency.","type":"string","minLength":1},"concurrency":{"description":"Caller-observed placement guard. component.repin currently requires mode:exact; guarded mode refuses before writes.","$ref":"#/components/schemas/CompositionConcurrency"}},"additionalProperties":false,"description":"PUT /components/:id body: every writable field, all optional; an omitted field is carried forward. Org/user are server-resolved; never accepted from the body.","examples":[{"name":"Renamed title"}]},"ComponentUpdateResponse":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"category":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]},"propSchema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"origin":{"type":"string","enum":["customer-owned","server-native"]},"ejectedFrom":{"type":"string","maxLength":200},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"examples":{"description":"Usage examples, as authored. A built-in primitive projects {name, mood?, params?, description?}; an authored component's examples are whatever it wrote, which is why the item is open. One shape for both directions: what you write here is what you read back.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"durationInFrames":{"type":"number","exclusiveMinimum":0},"manifest":{"description":"The stored runtime manifest (assets, graphics API, alpha policy) of an org-INSTALLED component: the same object the create/update body takes, so a manifest read back here can be written back unchanged. Built-in defaults have no stored manifest and omit it. Its `version` is always 2 (the contract version), unlike the entry's semver `version`.","$ref":"#/components/schemas/ComponentManifestV2"},"id":{"type":"string","description":"The entry's id: a `primitiveId` for a built-in, a `componentId` for an installed component."},"source":{"type":"string","enum":["default","installed"],"description":"'default' = built-in primitive (place by primitiveId); 'installed' = org-authored component (place by componentId)."},"kind":{"type":"string","enum":["component","transition","scene"],"description":"RENDER kind (component | transition | scene). NOT the ClipSource variant — see `placement` for how to author it on the timeline."},"version":{"type":"string","description":"The ENTRY's version: a semver string ('0.0.0' until an authored component is versioned). Distinct from `manifest.version`, which is the runtime contract version and is always the literal 2."},"propDefaults":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"textParam":{"description":"The param field that carries this primitive's primary text; null = no single text slot.","type":["string","null"]},"subtextParam":{"description":"The param field for secondary text (subtitle/byline); null = none.","type":["string","null"]},"format":{"$ref":"#/components/schemas/SceneFormat"},"intent":{"description":"Selection signal: a verb naming what this primitive accomplishes (e.g. 'product-trailer'). Match it to the beat you are authoring.","type":"string"},"useWhen":{"description":"When to use this — AND when not to. The negative guidance is load-bearing; read it before picking.","type":"string"},"pairsWith":{"description":"Authoring guidance: ids of primitives that COMPOSE well with this one in the same edit.","type":"array","items":{"type":"string"}},"avoidWith":{"description":"Authoring guidance: ids of primitives that CONFLICT with this one — do not place together.","type":"array","items":{"type":"string"}},"tags":{"description":"Free-text search keywords.","type":"array","items":{"type":"string"}},"mood":{"description":"Vibe/tone tags (e.g. 'cinematic', 'minimal'). Filter to match the edit's mood.","type":"array","items":{"type":"string"}},"tier":{"description":"Quality/applicability RANKING (a preference, not a flag). Prefer 'recommended'; reach for 'niche' only when its specific use-case is exactly the beat.","type":"string","enum":["recommended","standard","niche"]},"useCase":{"description":"The edit ROLE(s) this primitive fills — the dimension to filter by for a beat (e.g. 'intro', 'title-over-footage', 'grade').","type":"array","items":{"type":"string","enum":["intro","outro","full-scene","title-over-footage","transition","background","grade","emphasis","explainer","social-cut"]}},"fixedCopy":{"description":"On-screen strings this primitive BAKES — the read-side counterpart to propSchema. These literals render REGARDLESS of params (no param can change them); fork the source via get_component_source to edit them. Use this to see at author time what fixed copy (someone-else's marketing text, faux-code, faux-data) will appear before you render.","type":"array","items":{"type":"string"}},"brandBindings":{"description":"Params that can follow the project brand kit. Each {param, brandToken} says: set `param` to `brandToken` (a `$brand:` ref, e.g. '$brand:colors.accent') to track the brand instead of a literal. See the list response's `brandTokens` for the full ref vocabulary. Omitted when nothing is brand-bound.","type":"array","items":{"type":"object","properties":{"param":{"type":"string"},"brandToken":{"type":"string"}},"required":["param","brandToken"],"additionalProperties":false}},"placement":{"description":"How to author this entry as a ClipSource via apply_composition: the exact ClipSource `kind` + the id field to key it by. Built-ins place as {kind:'overlay'|'effect', primitiveId}; installed components place as {kind:'component', componentId}. A kind:'scene' primitive has no 'scene' ClipSource — it is placed as {kind:'overlay', primitiveId}.","$ref":"#/components/schemas/ComponentPlacement"},"warnings":{"description":"Non-blocking save-time advisories — the create/update SUCCEEDED. Currently: a `fontFamily` string literal referencing a NON-vendored font (a bare CSS generic like 'serif', or an unknown named family like 'Arial') whose LIVE-lane pixels vary by render host — re-author with a vendored family or 'Georgia'. Omitted when there is nothing to flag; only present on the create/update responses.","type":"array","items":{"type":"string"}},"repinned":{"description":"Present when the update named `projectId`: the composition whose placements moved to the new version.","type":"object","properties":{"compositionId":{"type":"string"},"pins":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Placements in that composition moved from the previous version to this one, nested scene surfaces included."},"etag":{"description":"The composition's ETag after the move; null when no pin moved.","type":["string","null"]}},"required":["compositionId","pins","etag"],"additionalProperties":false},"placementsPinnedToPrevious":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Placements across the org that still pin the previous version and will keep rendering it. Name `projectId` (and `compositionId`) on the update to move a composition's placements with it."}},"required":["name","description","category","propSchema","id","source","kind","version","placement","placementsPinnedToPrevious"],"additionalProperties":false,"description":"Updated component entry plus where its placements point."},"ComposeCreateRequest":{"type":"object","properties":{"suggestionId":{"type":"string","minLength":1},"fromComposition":{"description":"Reuse the project's current composition as the compose starting point (critique-retry path). The Director RE-AUTHORS graphics: if the current composition is client-authored and contains graphic clips (overlay/component/card), the request is refused (validation_error naming the clips) — render it verbatim with create_render instead. The director's own output (critique-retry) is exempt.","type":"boolean"},"briefId":{"description":"Compose from a persisted Brief (create_brief) — the intent-first door: every Brief field is HONORED or the request is refused loudly naming the field (window from beat moment-pinning; seeded graphics carried VERBATIM as locked clips; exclusions enforced; locale + caption emphasis threaded to the Director). Exactly ONE of suggestionId | fromComposition | briefId.","type":"string","minLength":1},"format":{"description":"Optional format override. Phase 2 ignores this — format precedence is project.compositionFormat → 9:16 fhd 30fps default.","$ref":"#/components/schemas/FormatSpec"},"scope":{"description":"RequestScope discriminated union (per compose-api-contract.md). Editor-only scopes (captions/overlay-track/broll/overlay-instance/segment) require an editor-session token; API tokens get 403 on those."},"critique":{"description":"Structured critique block (per compose-api-contract.md decision #11). Capped at 2KB total; per-criterion blocks capped at 500 chars.","type":"string","maxLength":2000},"parentJobId":{"description":"Pointer to the prior compose job this run iterates on. Surfaced on the resulting compose job as baselineComposeJobId.","type":"string"},"maxCandidates":{"description":"Ensemble size. Currently pinned to 1 — the multi-candidate ensemble is disabled pending a capacity bound, so any value >1 is ignored and every compose runs a single candidate. Still accepted for forward-compat; will honor [1, 5] again once re-enabled.","type":"integer","minimum":1,"maximum":5},"budgetUsd":{"description":"Per-job budget cap (USD). Clamped at the route against the org's composeMaxBudgetUsdPerJob setting.","type":"number","exclusiveMinimum":0},"qualityThreshold":{"description":"Composite-score accept threshold. Server default per contract.","type":"number","minimum":0,"maximum":10},"seed":{"description":"Deterministic seed for replay.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"clientNonce":{"description":"Opaque caller token that disambiguates intentional same-critique retries. Without it, identical (project, sug, seed, critique) tuples deduplicate; with it, retries create a fresh execution.","type":"string","maxLength":64},"holdAt":{"description":"Opt-in checkpoint gates. Each named stage pauses the compose at its boundary (status → awaiting_input) for client review via resume. Absent/empty ⇒ fully autonomous. Non-empty ⇒ the run is a single spine.","maxItems":3,"type":"array","items":{"type":"string","enum":["content","layout","motion"]}}},"additionalProperties":false,"description":"POST /projects/:id/compose body."},"ComposeCreateResponse":{"type":"object","properties":{"composeJobId":{"type":"string","description":"Opaque compose job id; pass to the SSE stream URL."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","failed"],"description":"queued = normal; failed = startup failed and the job is already terminal (the SSE stream will emit a single `job_failed` frame and close)."},"streamUrl":{"description":"Relative SSE endpoint to stream this job's events (per compose-api-contract.md).","type":"string"}},"required":["composeJobId","projectId","status"],"additionalProperties":false,"description":"POST /projects/:id/compose response."},"ComposeJobDetailResponse":{"type":"object","properties":{"composeJobId":{"type":"string"},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","awaiting_input","complete","failed","cancelled"]},"error":{"type":["string","null"]},"request":{"type":"object","properties":{"suggestionId":{"type":"string"},"fromComposition":{"type":"boolean"},"scope":{},"critique":{"type":"string"},"parentJobId":{"type":"string"},"maxCandidates":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"budgetUsd":{"type":"number"},"qualityThreshold":{"type":"number"}},"additionalProperties":false},"candidates":{"type":"array","items":{}},"winner":{"anyOf":[{"type":"object","properties":{"candidateIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"compositionRunId":{"type":"string"}},"required":["candidateIndex","compositionRunId"],"additionalProperties":false},{"type":"null"}]},"listUsd":{"type":"number"},"startedAt":{"type":"number"},"completedAt":{"type":["number","null"]},"advisoryResult":{"$ref":"#/components/schemas/ConsultResult"},"checkpoint":{"type":"object","properties":{"checkpointId":{"type":"string"},"stage":{"type":"string","enum":["content","layout","motion"]},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["checkpointId","stage","version"],"additionalProperties":false}},"required":["composeJobId","projectId","status","error","request","candidates","winner","startedAt","completedAt"],"additionalProperties":false},"ConsultResult":{"type":"object","properties":{"mode":{"type":"string","enum":["advise","amend","explore"]},"assessment":{"description":"Grounded critique of the CURRENT composition. Omitted for mode=advise.","type":"object","properties":{"editorial":{"type":"object","properties":{"score":{"type":"number"},"grounding":{"type":"string","enum":["measured","judged"]},"abstained":{"type":"boolean"},"reliability":{"type":"number"}},"required":["score","grounding","abstained"],"additionalProperties":false},"spatial":{"type":"object","properties":{"score":{"type":"number"},"grounding":{"type":"string","enum":["measured","judged"]},"abstained":{"type":"boolean"},"reliability":{"type":"number"}},"required":["score","grounding","abstained"],"additionalProperties":false},"brand":{"type":"object","properties":{"score":{"type":"number"},"grounding":{"type":"string","enum":["measured","judged"]},"abstained":{"type":"boolean"},"reliability":{"type":"number"}},"required":["score","grounding","abstained"],"additionalProperties":false},"caption":{"type":"object","properties":{"score":{"type":"number"},"grounding":{"type":"string","enum":["measured","judged"]},"abstained":{"type":"boolean"},"reliability":{"type":"number"}},"required":["score","grounding","abstained"],"additionalProperties":false}},"required":["editorial","spatial","brand","caption"],"additionalProperties":false},"proposals":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"candidateIndex":{"description":"Present for amend/explore — adopt via POST /compose/jobs/:jobId/select with this candidateIndex. Absent for advise.","type":"integer","minimum":0,"maximum":9007199254740991},"changeSummary":{"type":"array","items":{"type":"string"},"description":"Human-legible edit-pattern labels."},"boundToEtag":{"description":"The composition etag this proposal was computed against.","type":"string"},"expectedDelta":{"description":"Advisory per-criterion score lift; NOT authoritative pre-recalibration.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["label","changeSummary"],"additionalProperties":false}},"principles":{"type":"array","items":{"type":"string"},"description":"Reusable, grounded lessons for the client's next authoring."},"plan":{"description":"Present for mode=advise — the planner agent's ComposePlan (framing/cuts/captions/graphics intents) as GUIDANCE. The client agent reads it and re-authors; it is NOT converted to ops."},"checkpointId":{"description":"The durable kind:'score' Checkpoint minted from this advisory (evidence convergence — get_checkpoint re-reads the envelope later). Stamped at the consult success terminal.","type":"string"}},"required":["mode","proposals","principles"],"additionalProperties":false,"description":"The advisory envelope returned by a completed consult job (on ComposeJobDetailResponse.advisoryResult)."},"ComposeJobListItem":{"type":"object","properties":{"composeJobId":{"type":"string"},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","running","awaiting_input","complete","failed","cancelled"]},"suggestionId":{"type":"string"},"createdAt":{"type":"number"},"completedAt":{"type":["number","null"]}},"required":["composeJobId","projectId","status","createdAt","completedAt"],"additionalProperties":false},"ComposeJobListResponse":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/ComposeJobListItem"}}},"required":["jobs"],"additionalProperties":false},"ComposeSelectRequest":{"type":"object","properties":{"candidateIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"selectStrategy":{"type":"string","enum":["agent-authoritative","editor-merge","editor-replace"]},"ifMatch":{"type":"string"}},"required":["candidateIndex","selectStrategy"],"additionalProperties":false,"description":"POST /projects/:id/compose/jobs/:jobId/select body."},"ComposeSelectResponse":{"type":"object","properties":{"newCompositionEtag":{"type":"string"},"mergeResult":{"type":"object","properties":{"replayedEdits":{"type":"integer","minimum":0,"maximum":9007199254740991},"droppedEdits":{"type":"array","items":{"type":"object","properties":{"trackId":{"type":"string"},"clipId":{"type":"string"},"wordStartMs":{"type":"number"},"reason":{"type":"string","enum":["target_removed","conflict"]}},"required":["trackId","reason"],"additionalProperties":false}}},"required":["replayedEdits","droppedEdits"],"additionalProperties":false}},"required":["newCompositionEtag"],"additionalProperties":false,"description":"POST /projects/:id/compose/jobs/:jobId/select response."},"ComposeSessionOpenRequest":{"type":"object","properties":{"seedComposition":{},"leaseJobId":{"type":"string","minLength":1,"maxLength":64}},"additionalProperties":false,"example":{}},"Composition":{"type":"object","properties":{"v":{"type":"number","const":1},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},"tracks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"name":{"type":"string"},"enabled":{"type":"boolean"},"volume":{"type":"number","minimum":0,"maximum":4},"contents":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Gap duration (seconds)."}},"required":["id","startTime","duration"],"additionalProperties":false}]}}},"required":["id","kind","contents"],"additionalProperties":false}},"markers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0},"endTime":{"type":"number","minimum":0},"kind":{"type":"string","minLength":1},"name":{"type":"string"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","startTime","kind"],"additionalProperties":false}},"captions":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"derived"},"from":{"type":"object","properties":{"clipId":{"type":"string"}},"required":["clipId"],"additionalProperties":false},"segments":{"type":"array","items":{"type":"object","properties":{"words":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1},"startMs":{"type":"number","minimum":0,"description":"Word start on the composition timeline, in milliseconds."},"endMs":{"type":"number","minimum":0,"description":"Word end on the composition timeline, in milliseconds."},"emphasis":{"type":"boolean"},"annotate":{"type":"string","enum":["circle","underline"]}},"required":["text","startMs","endMs"],"additionalProperties":false}}},"required":["words"],"additionalProperties":false}},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"position":{"type":"string","enum":["top","center","bottom"]},"region":{"description":"Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height.","type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisGradient":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"maxWidthPercent":{"type":"number","exclusiveMinimum":0,"maximum":100}},"additionalProperties":false},"layouts":{"type":"array","items":{"type":"object","properties":{"segmentIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordStartIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordEndIndex":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Exclusive word index in the saved caption segment."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"scale":{"type":"number","minimum":0.25,"maximum":4},"rotation":{"type":"number","minimum":-45,"maximum":45},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0}},"additionalProperties":false},"holdThroughWordIndex":{"description":"Inclusive saved-word index in this segment. The layout stays visible until that word ends.","type":"integer","minimum":0,"maximum":9007199254740991},"wordMarks":{"type":"array","items":{"type":"object","properties":{"wordIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"emphasis":{"type":"boolean"},"annotate":{"anyOf":[{"type":"string","enum":["circle","underline"]},{"type":"null"}]}},"required":["wordIndex"],"additionalProperties":false}},"wordSignature":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["segmentIndex","wordStartIndex","wordEndIndex","region","wordSignature"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]}},"required":["source","from","segments"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"authored"},"segments":{"type":"array","items":{"type":"object","properties":{"words":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1},"startMs":{"type":"number","minimum":0,"description":"Word start on the composition timeline, in milliseconds."},"endMs":{"type":"number","minimum":0,"description":"Word end on the composition timeline, in milliseconds."},"emphasis":{"type":"boolean"},"annotate":{"type":"string","enum":["circle","underline"]}},"required":["text","startMs","endMs"],"additionalProperties":false}}},"required":["words"],"additionalProperties":false}},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"position":{"type":"string","enum":["top","center","bottom"]},"region":{"description":"Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height.","type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisGradient":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"maxWidthPercent":{"type":"number","exclusiveMinimum":0,"maximum":100}},"additionalProperties":false},"layouts":{"type":"array","items":{"type":"object","properties":{"segmentIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordStartIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordEndIndex":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Exclusive word index in the saved caption segment."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"scale":{"type":"number","minimum":0.25,"maximum":4},"rotation":{"type":"number","minimum":-45,"maximum":45},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0}},"additionalProperties":false},"holdThroughWordIndex":{"description":"Inclusive saved-word index in this segment. The layout stays visible until that word ends.","type":"integer","minimum":0,"maximum":9007199254740991},"wordMarks":{"type":"array","items":{"type":"object","properties":{"wordIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"emphasis":{"type":"boolean"},"annotate":{"anyOf":[{"type":"string","enum":["circle","underline"]},{"type":"null"}]}},"required":["wordIndex"],"additionalProperties":false}},"wordSignature":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["segmentIndex","wordStartIndex","wordEndIndex","region","wordSignature"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]}},"required":["source","segments"],"additionalProperties":false}],"type":"object"},"license":{"type":"object","properties":{"type":{"type":"string","minLength":1},"source":{"type":"string"},"notes":{"type":"string"}},"required":["type"],"additionalProperties":false},"accessibility":{"type":"object","properties":{"audioDescriptionTrackId":{"type":"string"},"captionsTrackId":{"type":"string"},"signLanguageTrackId":{"type":"string"},"notes":{"type":"string"}},"additionalProperties":false}},"required":["v","format","tracks"],"additionalProperties":{},"description":"Canonical composition wire shape (multi-track; carries reframe, captions, markers).","examples":[{"v":1,"format":{"aspectRatio":"16:9","fps":30},"tracks":[]}]},"CompositionApplyRequest":{"type":"object","properties":{"ops":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/CompositionOp"}},"componentExecutionVersions":{"minItems":1,"maxItems":1,"type":"array","items":{"type":"number","const":3}},"builtinSources":{"minItems":1,"maxItems":512,"type":"array","items":{"type":"object","properties":{"scope":{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceVersion":{"type":"number","const":3}},"required":["scope","componentId","sourceVersionId","sourceVersion"],"additionalProperties":false}},"expectedBrandIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"concurrency":{"description":"Version 1 shared dependency admission. Guarded requests must name the observed immutable composition with composition_id or concurrency.compositionId; changed or missing dependencies refuse the entire batch.","$ref":"#/components/schemas/CompositionConcurrency"},"if_match":{"description":"Optional OCC precondition — the strong etag (`\"<hex>\"`) the caller last saw. On mismatch the batch is rejected (409 stale_etag) before any op applies.","type":"string"},"dry_run":{"description":"When true, validate the batch (apply + projection accept/reject guards) WITHOUT persisting. Returns `{ valid, errors }` instead of applying.","type":"boolean"},"composition_id":{"description":"Target a SPECIFIC composition instead of the project's active one. Omit it and the project's active composition is edited, which is the default and the common case. `preview_frame` and `create_render` already accept a compositionId; this closes the gap so a second composition minted with `new_composition` can actually be authored into — build variant A, mint B, edit B, preview both. Mutually exclusive with `session_id`, which targets the session's scratch.","type":"string"},"session_id":{"description":"Optional compose-session id. When present, the ops target the session's SCRATCH composition (a derived sibling) instead of the project's active composition — the server never mutates active until commit.","type":"string"}},"required":["ops"],"additionalProperties":false,"description":"POST /projects/:id/composition/apply body — a batch of CompositionOps.","examples":[{"ops":[{"type":"clip.remove","clipId":"observed-clip"}]}]},"CompositionOp":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"scene.add"},"clipId":{"type":"string"},"trackId":{"type":"string"},"newTrack":{"type":"boolean"},"newTrackId":{"type":"string"},"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0},"scene":{"$ref":"#/components/schemas/SceneShotSpecV2"},"assets":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"transitionIn":{"$ref":"#/components/schemas/TransitionSpec"}},"required":["type","clipId","startTime","duration","scene","assets"],"additionalProperties":false,"description":"Author a scene shot and place it on a dedicated overlay track. The host validates the scene, generates and registers an immutable wrapper component source, and emits the ordinary track/clip operations carrying `props.componentRef` — you edit a scene SPEC, never wrapper TSX or a source hash. Registration and the composition update are ONE undoable edit; a failure publishes nothing and leaves no clip pointing at an unresolved source. Pass EXACTLY ONE of `trackId` (an existing dedicated scene track) or `newTrack: true` (mint one). That track holds scene-shot clips and gaps only — no generic component/primitive/media clips in v1 — and existing generic overlay tracks are unaffected. Scene clips use front zPlane and full-frame placement: outer per-clip `region`, `position`, `scale`, `rotation`, `fit`, `effects`, `animate`, `params.transition`, `params.sequenceGroup` and internal fadeIn/fadeOut are REFUSED with a path, because the shot's own layer transforms are the single transform owner. TEXT: `space: \"screen\"` text is composed above the world result, stays fixed in the frame and stays sharp through focus; `space: \"world\"` text is rasterized into the 3D scene, moves with the camera and is occluded by geometry. Screenshots and world text are UNLIT and colour-managed so product UI colours are not tinted by the studio lighting, while device bodies are lit and cast shadows; an unlit surface still occludes. SCOPE GAP (pre-existing, neither closed nor changed by scene shots): global wrap effects — composition-level grades and camera effects — do not reach front-overlay clips, so they do not affect a scene shot. Author the look INSIDE the shot (`post.grain`, `post.vignette`, `post.focus`, `backdrop`, `environment`) instead. DISCOVERY: there is no built-in scene primitive to look up in list_catalog; the wrapper this operation registers appears afterwards as an ordinary INSTALLED component under the existing catalog rules. ASSETS: `assets` binds each slot name a layer references to a media id in the same project, and the slot's declared KIND decides what it admits — an image slot takes PNG, JPEG or WebP, a video slot MP4 or WebM. Binding the wrong kind is refused with the slot's path."},{"type":"object","properties":{"type":{"type":"string","const":"scene.update"},"clipId":{"type":"string"},"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0},"scene":{"$ref":"#/components/schemas/SceneShotSpecV2"},"assets":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"transitionIn":{"$ref":"#/components/schemas/TransitionSpec"}},"required":["type","clipId"],"additionalProperties":false,"description":"Revise a scene shot in place by clip id. Send a replacement `scene` and/or `assets`; timing changes use the ordinary clip timing fields (`startTime`, `duration`, `transitionIn`). Omitted fields keep their persisted values and the MERGED result is re-validated as a whole, so a partial edit cannot leave the shot invalid. Changing only values or asset IDs updates props and bindings and REUSES the pinned source; changing the referenced SLOT SET regenerates the wrapper manifest and registers a new immutable source version atomically. Undo restores the source reference, spec, bindings and timing together. Topology, asset bindings, text content, font properties, device kind and colours are STATIC within a shot's animation — change them here (a revised spec) rather than trying to animate them. This is not a source trim or slip: a shortened or extended clip resamples the SAME normalized animation over its new duration, and trim/slip requests on generated animation are rejected rather than reinterpreted as media trims. In one batch, `scene.update` may target a shot added by an earlier `scene.add`. ASSETS: `assets` binds each slot name a layer references to a media id in the same project, and the slot's declared KIND decides what it admits — an image slot takes PNG, JPEG or WebP, a video slot MP4 or WebM. Binding the wrong kind is refused with the slot's path."},{"type":"object","properties":{"type":{"type":"string","const":"clip.add"},"clip":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false},"trackId":{"type":"string"},"newTrack":{"type":"boolean"},"newTrackId":{"type":"string"}},"required":["type","clip"],"additionalProperties":false,"description":"Add a clip to the timeline. The clip self-routes to a track by FAMILY (`clip.kind`, else derived from `source.kind`, else the target track) — a `media` clip MUST carry `kind` (video|audio|image) or a `trackId`, else it is rejected as ambiguous. `trackId` targets an existing SAME-family track; `newTrack:true` (with optional pinned `newTrackId`) creates a fresh track of that family."},{"type":"object","properties":{"type":{"type":"string","const":"clip.remove"},"clipId":{"type":"string"}},"required":["type","clipId"],"additionalProperties":false,"description":"Remove a clip by id (located across every track)."},{"type":"object","properties":{"type":{"type":"string","const":"clip.update"},"clipId":{"type":"string"},"patch":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"additionalProperties":false}},"required":["type","clipId","patch"],"additionalProperties":false,"description":"Patch an existing clip by id (cross-family). The patch is a partial TimelineClip. NOTE: `source` is REPLACED wholesale — the patch merges at the top level only, so a partial `source` WIPES the source fields you omit. Patch the whole source object when changing it. (To change reframe/excluded ranges, prefer setCropIntents / addExcludedRange, not a source patch.)"},{"type":"object","properties":{"type":{"type":"string","const":"removeClipsByMediaId"},"mediaId":{"type":"string"}},"required":["type","mediaId"],"additionalProperties":false,"description":"Remove EVERY clip sourced from a given mediaId (e.g. after deleting that media)."},{"type":"object","properties":{"type":{"type":"string","const":"loadOverlays"},"clips":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0,"description":"Timeline start (seconds)."},"duration":{"type":"number","exclusiveMinimum":0,"description":"Clip duration (seconds)."},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"media"},"mediaId":{"type":"string","minLength":1},"trim":{"type":"object","properties":{"start":{"type":"number","minimum":0,"description":"Source trim start (seconds)."},"end":{"type":"number","minimum":0,"description":"Source trim end (seconds)."}},"required":["start","end"],"additionalProperties":false},"excludedRanges":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number","minimum":0},"end":{"type":"number","minimum":0},"reason":{"type":"string"}},"required":["start","end"],"additionalProperties":false}},"volume":{"type":"number","minimum":0,"maximum":4},"muted":{"type":"boolean"},"playbackRate":{"type":"number","exclusiveMinimum":0},"sync":{"type":"string","enum":["video","independent"]},"kenBurns":{"type":"string","enum":["in","out","pan-l","pan-r","none"]},"volumeDb":{"type":"number"},"fadeInMs":{"type":"number","minimum":0},"fadeOutMs":{"type":"number","minimum":0},"loop":{"type":"boolean"},"audioRole":{"type":"string","enum":["sfx","music","vo","ambience"]},"duck":{"type":"object","properties":{"duckDb":{"type":"number","maximum":0},"attackMs":{"type":"number","minimum":0},"releaseMs":{"type":"number","minimum":0},"windows":{"type":"array","items":{"type":"object","properties":{"startMs":{"type":"number"},"endMs":{"type":"number"}},"required":["startMs","endMs"],"additionalProperties":false}}},"required":["duckDb","attackMs","releaseMs"],"additionalProperties":false},"anchor":{"type":"object","properties":{"clipId":{"type":"string","minLength":1},"offsetMs":{"type":"number"}},"required":["clipId","offsetMs"],"additionalProperties":false},"reframe":{"type":"object","properties":{"segments":{"minItems":1,"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}}},"required":["segments"],"additionalProperties":false}},"required":["kind","mediaId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"component"},"componentId":{"type":"string","minLength":1},"props":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"assets":{"description":"Manifest asset slot → project media id. At mount each slot arrives as `assets[slot].handle`, a fetchable URL for <Img>/<Video>/<Audio>; `props` becomes `params` and never carries an asset URL.","type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"string","minLength":1}},"assetTiming":{"type":"object","propertyNames":{"type":"string","minLength":1},"additionalProperties":{"type":"object","properties":{"trimStartSec":{"type":"number","minimum":0},"trimEndSec":{"type":"number","exclusiveMinimum":0},"playbackRate":{"type":"number","exclusiveMinimum":0,"maximum":16},"endPolicy":{"type":"string","enum":["loop","hold","reject"]},"timelineOffsetSec":{"type":"number","minimum":0}},"required":["endPolicy"],"additionalProperties":false}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"execution":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"placement":{"oneOf":[{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"clip"}},"required":["version","kind"],"additionalProperties":false},{"type":"object","properties":{"version":{"type":"number","const":3},"kind":{"type":"string","const":"content-slots"},"slots":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"object","properties":{"targetClipIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"ownership":{"type":"string","enum":["reference","exclusive"]}},"required":["targetClipIds","ownership"],"additionalProperties":false}}},"required":["version","kind","slots"],"additionalProperties":false}],"type":"object"}},"required":["kind","componentId","props"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"overlay"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"zPlane":{"type":"string","enum":["front","behind-subject"]},"anchor":{"type":"object","properties":{"space":{"type":"string","const":"scene"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["space","x","y"],"additionalProperties":false},"parallax":{"type":"number","minimum":-0.3,"maximum":0.3}},"required":["kind","primitiveId","params"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"effect"},"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"targetTrackIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"wrapperOrder":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"card"},"html":{"type":"string","minLength":1,"description":"Your card's HTML — rendered VERBATIM as the graphic (shell motion via applyMotionPreset in a FOLLOWING call). CANVAS CONTRACT: the card renders in a viewport equal to the composition format's pixel frame (1080×1920 at 9:16 fhd); the root is NOT auto-pinned — declare explicit width/height matching the frame (box-sizing:border-box) and anchor content with flex/grid; position:absolute;inset:0 on the root does NOT fill the frame; for edge-to-edge backgrounds add an inner absolutely-positioned layer with generous negative inset. Overlay compositing applies a ~92% safe-area inset — keep critical copy away from the extreme edges. FONTS: name a family from GET /v1/fonts (list_render_fonts) — the renderer loads those faces for the card and waits for them, so `font-family: Inter` draws Inter. `@import` and remote font files are REFUSED: the card renders with no network. A family that is not on that list has no bytes behind it and the browser falls back, so end any stack with a generic (`Inter, sans-serif`) rather than relying on a system face being present."},"tokens":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"zPlane":{"type":"string","const":"front"}},"required":["kind","html"],"additionalProperties":false}],"type":"object"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"opacity":{"type":"number","minimum":0,"maximum":1},"scale":{"type":"number","exclusiveMinimum":0},"rotation":{"type":"number"},"position":{"type":"object","properties":{"x":{"type":"number","minimum":-1,"maximum":2},"y":{"type":"number","minimum":-1,"maximum":2}},"required":["x","y"],"additionalProperties":false,"description":"Clip CENTRE as a fraction of the frame: {x:0.5,y:0.5} is dead centre, 0 to 1 is inside the frame, and a little overshoot (down to -1, up to 2) is how an entrance starts off-canvas. NOT pixels: the renderer maps x to `left: x*100%`, so `x: 180` sits 180 frame-widths away and draws nothing."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"fit":{"type":"string","enum":["cover","contain"]},"captionVisibility":{"description":"Video media clip only. Hide native captions while this clip is topmost and covers the lower picture, or when an opaque, effect-free clip has an explicitly full-frame region, even with fit:contain. Caption words and timings remain stored and resume when another visible clip takes over.","type":"string","enum":["visible","hidden"]},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}},"transitionIn":{"type":"object","properties":{"type":{"type":"string","minLength":1},"duration":{"type":"number","exclusiveMinimum":0},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"fromClipId":{"type":"string","minLength":1},"toClipId":{"type":"string","minLength":1},"handlePolicy":{"type":"string","const":"outgoing-overrun-at-cut-v1"}},"required":["type","duration"],"additionalProperties":false},"linkGroupId":{"type":"string","minLength":1},"animate":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"minItems":2,"type":"array","items":{"type":"object","properties":{"time":{"type":"number","minimum":0},"value":{"type":"number"},"easing":{"anyOf":[{"type":"string","enum":["linear","ease","easeIn","easeOut","easeInOut"]},{"type":"object","properties":{"cubicBezier":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":4,"maxItems":4}},"required":["cubicBezier"],"additionalProperties":false}]}},"required":["time","value"],"additionalProperties":false}},"description":"Keyframe channels, clip-relative seconds. Each channel's values use the SAME unit as the scalar it animates: `opacity` 0 to 1, `scale` a multiplier (>0), `rotation` degrees, `position.x`/`position.y` a FRACTION of the frame like `position` (0.5 = centre; NOT pixels), `volume` 0 to 4."}},"required":["id","startTime","duration","source"],"additionalProperties":false}}},"required":["type","clips"],"additionalProperties":false,"description":"Replace the overlay channel wholesale with the given clips (bulk set, not a merge)."},{"type":"object","properties":{"type":{"type":"string","const":"addMarker"},"marker":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0},"endTime":{"type":"number","minimum":0},"kind":{"type":"string","minLength":1},"name":{"type":"string"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","startTime","kind"],"additionalProperties":false}},"required":["type","marker"],"additionalProperties":false,"description":"Add a timeline marker (a named time point/range; carry extensions in `metadata`)."},{"type":"object","properties":{"type":{"type":"string","const":"removeMarker"},"markerId":{"type":"string"}},"required":["type","markerId"],"additionalProperties":false,"description":"Remove a marker by id."},{"type":"object","properties":{"type":{"type":"string","const":"updateMarker"},"markerId":{"type":"string"},"updates":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0},"endTime":{"type":"number","minimum":0},"kind":{"type":"string","minLength":1},"name":{"type":"string"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"additionalProperties":false}},"required":["type","markerId","updates"],"additionalProperties":false,"description":"Patch a marker's fields by id (partial merge)."},{"type":"object","properties":{"type":{"type":"string","const":"setCropIntents"},"clipId":{"type":"string"},"segments":{"anyOf":[{"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Segment START in seconds, clip-relative. Segments tile the clip's duration in order."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Segment END in seconds, clip-relative. The span (endSec − startSec) is this segment's duration — the window `ease` ramps over."},"focus":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"frame-center"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"point"},"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1}},"required":["mode","x","y"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"face"},"faceId":{"type":"string","minLength":1},"shotScale":{"type":"string","enum":["close","standard","wide"]}},"required":["mode","faceId"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"all-faces"}},"required":["mode"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"active-speaker"}},"required":["mode"],"additionalProperties":false}],"description":"WHO/WHAT the camera tracks this segment (the reframe center), selected by `mode`: `frame-center` = no tracking, hold the geometric center (static/graphic footage, or a pure zoom); `point` = lock to a fixed source-normalized {x,y} (a non-moving on-screen element); `face` = track a detected face by `faceId` (from get_media_context), with optional `shotScale` close|standard|wide for tightness; `all-faces` = frame the bounding box of every detected face (group/ensemble shots); `active-speaker` = follow whoever is speaking (diarized talking-head / podcast). Pick by what the beat is about; pair with `zoom` for how tight.","type":"object"},"intent":{"description":"Optional editorial LABEL for diff/log readability (e.g. 'speaker-tight', 'wide-context'). Cosmetic — NOT honored by the derive math and excluded from the variant cache key.","type":"string"},"zoom":{"description":"How TIGHT the framing is — the fraction of the source the output viewport shows. <1 punches IN (a smaller source fraction, magnified to fill the frame); 1 = the full frame (no crop). ~0.6–0.8 is a moderate push-in, ~0.5 a tight close-up, 0.1 the maximum zoom. There is NO zoom-OUT past the full frame (max 1). Omit for the full frame. MUTUALLY EXCLUSIVE with `focus.shotScale` — a face-tracked shot is sized EITHER by the editorial scale (shotScale, which the bake calibrates to the detected face) OR by an explicit zoom, never both. A segment carrying both is REJECTED: shotScale wins at bake time and the zoom would be silently discarded.","type":"number","minimum":0.1,"maximum":1},"ease":{"description":"Zoom/center ramp DURATIONS in SECONDS at this segment's edges — NOT a unitless 0–1 curve. ~0.3–0.6s reads as a snappy push; >1s reads sluggish. Keep `in` + `out` ≤ the segment's duration (endSec − startSec): the two edges share the span, so to ramp across the WHOLE segment set one edge to the full duration and the other to 0. Omit for an instant cut to this framing.","type":"object","properties":{"in":{"type":"number","minimum":0,"description":"Ease-IN ramp DURATION in seconds at the segment START."},"out":{"type":"number","minimum":0,"description":"Ease-OUT ramp DURATION in seconds at the segment END."}},"required":["in","out"],"additionalProperties":false},"bias":{"description":"Optional FINE framing nudge off the focus center, source-normalized in [−0.3, 0.3]. A small correction (headroom, rule-of-thirds), NOT a reframe — use `focus`/`zoom` for the actual shot. Omit (treated as 0) to sit dead-center on the focus.","type":"object","properties":{"x":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Horizontal nudge, source-normalized (+ = right)."},"y":{"type":"number","minimum":-0.3,"maximum":0.3,"description":"Vertical nudge, source-normalized (+ = down)."}},"required":["x","y"],"additionalProperties":false}},"required":["startSec","endSec","focus"],"additionalProperties":false}},{"type":"null"}]}},"required":["type","clipId","segments"],"additionalProperties":false,"description":"Set (or CLEAR, with `segments: null`) the camera/reframe channel on a MEDIA clip — the time-aligned source→output viewport (focus, zoom, ease, bias). This is the PREFERRED way to author reframing; do NOT reframe via a whole-source `clip.update` patch. Segments tile the clip's duration."},{"type":"object","properties":{"type":{"type":"string","const":"setEffects"},"clipId":{"type":"string"},"effects":{"type":"array","items":{"type":"object","properties":{"primitiveId":{"type":"string","minLength":1},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"id":{"type":"string","minLength":1},"component":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"window":{"type":"object","properties":{"startTime":{"type":"number","minimum":0},"duration":{"type":"number","exclusiveMinimum":0}},"required":["startTime","duration"],"additionalProperties":false}},"additionalProperties":false}}},"required":["type","clipId","effects"],"additionalProperties":false,"description":"Set (or CLEAR, with `effects: []`) a clip's EFFECT channel — the registered effect primitives stacked onto that clip, each `{ primitiveId, params? }`. WHOLESALE: the array REPLACES the clip's current effects, so send the full stack (read the clip first to add one). This is the ONLY way to change effects on an existing clip — do NOT reach for a `clip.update` patch, whose top-level merge is the source-clobbering footgun documented above."},{"type":"object","properties":{"type":{"type":"string","const":"setCaptionStyle"},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"position":{"type":"string","enum":["top","center","bottom"]},"region":{"description":"Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height.","type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisGradient":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"maxWidthPercent":{"type":"number","exclusiveMinimum":0,"maximum":100}},"additionalProperties":false}},"required":["type","style"],"additionalProperties":false,"description":"Merge style overrides (font/color/position/emphasis) onto the composition's caption layer. Partial — omitted fields keep their current value; creates the caption container if absent."},{"type":"object","properties":{"type":{"type":"string","const":"setCaptionLayouts"},"layouts":{"type":"array","items":{"type":"object","properties":{"segmentIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordStartIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"wordEndIndex":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Exclusive word index in the saved caption segment."},"region":{"type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"scale":{"type":"number","minimum":0.25,"maximum":4},"rotation":{"type":"number","minimum":-45,"maximum":45},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0}},"additionalProperties":false},"holdThroughWordIndex":{"description":"Inclusive saved-word index in this segment. The layout stays visible until that word ends.","type":"integer","minimum":0,"maximum":9007199254740991},"wordMarks":{"type":"array","items":{"type":"object","properties":{"wordIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"emphasis":{"type":"boolean"},"annotate":{"anyOf":[{"type":"string","enum":["circle","underline"]},{"type":"null"}]}},"required":["wordIndex"],"additionalProperties":false}}},"required":["segmentIndex","wordStartIndex","wordEndIndex","region"],"additionalProperties":false}}},"required":["type","layouts"],"additionalProperties":false,"description":"Replace native caption placements without changing transcript words or timings. Each layout references a half-open word-index range in one saved segment; a one-word range is valid. region places that group independently, optional bounded scale/rotation/style changes its look, and holdThroughWordIndex keeps it visible through a later saved word in the same segment. All words in a placed range occupy one page; rendering refuses a range that cannot fit its box, so enlarge region or split the range. The box reserves horizontal space of 1.6 font sizes and vertical space of 0.8 font sizes for padding, with at most three lines. Unreferenced words keep the default caption layout. Word ranges must not overlap. Reapply after caption regeneration or timeline cuts."},{"type":"object","properties":{"type":{"type":"string","const":"setCaptionDepth"},"zPlane":{"type":"string","enum":["front","behind-subject"]}},"required":["type","zPlane"],"additionalProperties":false,"description":"Set the caption compositing plane. Use `behind-subject` to place captions behind the segmented foreground subject; use `front` for conventional captions above all video layers."},{"type":"object","properties":{"type":{"type":"string","const":"setCaptions"},"segments":{"type":"array","items":{"type":"object","properties":{"words":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1},"startMs":{"type":"number","minimum":0,"description":"Word start on the composition timeline, in milliseconds."},"endMs":{"type":"number","minimum":0,"description":"Word end on the composition timeline, in milliseconds."},"emphasis":{"type":"boolean"},"annotate":{"type":"string","enum":["circle","underline"]}},"required":["text","startMs","endMs"],"additionalProperties":false}}},"required":["words"],"additionalProperties":false}},"style":{"type":"object","properties":{"fontFamily":{"type":"string","minLength":1},"fontSize":{"description":"Font size as % of composition height (1-15, default 5). NOT px.","type":"number","minimum":1,"maximum":15},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"color":{"type":"string","minLength":1},"highlightColor":{"type":"string","minLength":1},"backgroundColor":{"type":"string"},"plate":{"type":"string","enum":["glass","solid","none"]},"position":{"type":"string","enum":["top","center","bottom"]},"region":{"description":"Optional caption layout box {x,y,w,h} in normalized output-frame coordinates. Overrides position; text starts at its top edge and wraps/pages within its width and height.","type":"object","properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"w":{"type":"number","exclusiveMinimum":0,"maximum":1},"h":{"type":"number","exclusiveMinimum":0,"maximum":1}},"required":["x","y","w","h"],"additionalProperties":false},"textTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"letterSpacing":{"description":"Base caption glyph spacing in pixels.","type":"number","minimum":-5,"maximum":20},"wordGapEm":{"description":"Gap between caption runs as a multiple of base font size; default 0.35.","type":"number","minimum":0,"maximum":2},"lineGapEm":{"description":"Gap between caption lines as a multiple of base font size; default 0.25.","type":"number","minimum":0,"maximum":2},"emphasisColor":{"type":"string"},"emphasisGradient":{"type":"string"},"emphasisScale":{"type":"number","exclusiveMinimum":0},"emphasisFontFamily":{"type":"string"},"emphasisFontWeight":{"type":"integer","minimum":100,"maximum":900},"emphasisTextTransform":{"type":"string","enum":["none","uppercase","capitalize"]},"emphasisLetterSpacing":{"type":"number"},"emphasisFontStyle":{"type":"string","enum":["normal","italic"]},"entrance":{"type":"string","enum":["none","fade","word-pop","stagger-up"]},"entranceMs":{"type":"number","minimum":0},"entranceStaggerMs":{"type":"number","minimum":0},"exitMs":{"type":"number","minimum":0},"emphasisPlate":{"type":"boolean"},"emphasisPlateColor":{"type":"string"},"emphasisPlateTextColor":{"type":"string"},"emphasisPlateAltColor":{"type":"string"},"emphasisPlateAltTextColor":{"type":"string"},"emphasisPlateRadius":{"type":"number","minimum":0},"emphasisPlatePadX":{"type":"number"},"emphasisPlatePadY":{"type":"number"},"emphasisPlateReveal":{"description":"Grow a shared emphasis plate as saved words appear while reserving its final layout width.","type":"boolean"},"annotationColor":{"type":"string"},"annotationStrokeWidth":{"description":"Annotation stroke width in its 100×100 SVG coordinate system; default 4.","type":"number","minimum":0.5,"maximum":12},"annotationTexture":{"description":"Native annotation stroke finish; default clean.","type":"string","enum":["clean","pencil"]},"maxWidthPercent":{"type":"number","exclusiveMinimum":0,"maximum":100}},"additionalProperties":false}},"required":["type","segments"],"additionalProperties":false,"description":"Replace the caption SEGMENTS wholesale — author the word-timed caption layer directly (each segment = one sentence/page of `words` with timeline-ms `startMs`/`endMs`, optional `emphasis`). This is how a client with its OWN word timings (e.g. a generated VO take) gets word-synced captions without a source transcript; the compose lane's transcript slice writes the same layer. `style`, when given, merges with setCaptionStyle semantics; an omitted style keeps the existing one. Renderer paginates within a segment and never pools words across two — keep segments sentence-bounded."},{"type":"object","properties":{"type":{"type":"string","const":"captions.fromTranscript"},"mediaId":{"type":"string","minLength":1},"window":{"type":"object","properties":{"startSec":{"type":"number","minimum":0},"endSec":{"type":"number","exclusiveMinimum":0}},"required":["startSec","endSec"],"additionalProperties":false}},"required":["type","mediaId"],"additionalProperties":false,"description":"Attach caption CONTENT from the media's cached transcript — no pasting words. ROUTE-MATERIALIZED like applyMotionPreset/materializeGrid: the server slices the word-timed transcript to `window` (source seconds; absent = the whole media), rebases times, sentence-splits into segments, and applies it as `setCaptions`. 422 media_no_transcript when the media has no transcript or no words in the window. For your OWN word timings use setCaptions directly. For edited multi-clip timelines, use captions.fromComposition after saving the edits; that operation projects all selected track clips, trims, exclusions, and placements."},{"type":"object","properties":{"type":{"type":"string","const":"captions.fromComposition"},"trackId":{"type":"string","minLength":1}},"required":["type","trackId"],"additionalProperties":false,"description":"Snapshot word-timed captions from the SAVED edits on one explicit enabled video or audio track. The host reads each source media transcript, projects words through clip trim, excluded ranges and placement, then replaces the caption segments. This is route-materialized to setCaptions; call it AFTER persisting clip edits and call it again when those edits change. The existing caption style and depth are preserved. Missing transcripts, unsupported clips, inconsistent clip durations, and overlapping audible clips fail loud. Playback rate scales source word times and playable duration on both audio and video tracks."},{"type":"object","properties":{"type":{"type":"string","const":"applyMotionPreset"},"clipId":{"type":"string"},"preset":{"type":"string"},"params":{"type":"object","properties":{"enterMs":{"type":"number"},"exitMs":{"type":"number"},"staggerMs":{"type":"number"}},"additionalProperties":false}},"required":["type","clipId","preset"],"additionalProperties":false,"description":"Shell a STATIC `card` clip with a frame-driven MOTION preset — the public card-shelling op (the layout renders VERBATIM; only the container animates in/out). The server wraps the card in the chosen `preset` (fade-up / slide-in-left / slide-in-right / scale-pop / stagger-reveal), transpiles it, mints it as a LIVE component, and swaps the clip source to that component (the bakeless live lane — no box). `params` tunes timing (`enterMs`/`exitMs`, `staggerMs` for stagger-reveal). The target must be a static card (components already carry motion; library overlays already move); re-run overwrites idempotently ONLY while the target is still a card (an uncompilable shell); once shelled, the clip is a COMPONENT — to change its motion, remove and re-add the card, then re-shell. Honored under `dry_run` (validates preset + target without transpiling or persisting). ORDERING: the preset resolves its target against the PERSISTED composition — a card added in the SAME batch is not yet visible to it. Persist the clip.add batch first, then shell in a following call."},{"type":"object","properties":{"type":{"type":"string","const":"materializeGrid"},"clipId":{"type":"string"},"grid":{"type":"string","enum":["beat","word","shot"]},"maxMarkers":{"type":"integer","exclusiveMinimum":0,"maximum":2000}},"required":["type","clipId","grid"],"additionalProperties":false,"description":"Materialize a clip's SOURCE-media temporal GRID as timeline markers — the rhythm authority you cut to. `grid:\"beat\"` reads a MUSIC bed's beat map (get_media_context.beatGrid), `grid:\"word\"` the VO word onsets (wordGrid); each grid point is projected from media time to TIMELINE time through the clip's placement (startTime, trim, playbackRate, excludedRanges) and written as a `kind:\"beat\"|\"word\"` marker (`metadata.sourceClipId` set). Points outside the clip's visible window are skipped. Re-running REPLACES the prior markers from the same clip+grid (idempotent). Land cuts and transition MIDPOINTS on the markers (a 0.5s transition starts 0.25s before its marker). `maxMarkers` (default 500, ceiling 2000) — exceeding it fails loud with the count. `grid:\"shot\"` is not yet exposed (shot_grid_unavailable). The target must be a media clip; absent evidence fails loud (grid_unavailable) naming how to get it (declare audioRole:\"music\" at ingest / transcribe)."},{"type":"object","properties":{"type":{"type":"string","const":"setFormat"},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]}},"required":["aspectRatio"],"additionalProperties":false}},"required":["type","format"],"additionalProperties":false,"description":"Set the output format — `aspectRatio` (16:9|9:16|1:1|4:5) plus optional `fps` and `resolution`. Merges: an omitted field keeps the current value."},{"type":"object","properties":{"type":{"type":"string","const":"addTrack"},"kind":{"type":"string","enum":["video","audio","image","overlay","effect"]},"name":{"type":"string"},"id":{"type":"string"}},"required":["type","kind"],"additionalProperties":false,"description":"Add an EMPTY track of a given family (video|audio|image|overlay|effect). Optional pinned `id`. The new track is appended, so it starts at the BACK: index 0 is the top layer and higher indices are further back (see `reorderTracks`). Track order only ranks clips on the same plane — every overlay draws above the video lane unless its `zPlane` is `behind-subject`, whatever its track index."},{"type":"object","properties":{"type":{"type":"string","const":"removeTrack"},"trackId":{"type":"string"}},"required":["type","trackId"],"additionalProperties":false,"description":"Remove a track AND all its clips by id."},{"type":"object","properties":{"type":{"type":"string","const":"updateTrack"},"trackId":{"type":"string"},"updates":{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"}},"additionalProperties":false}},"required":["type","trackId","updates"],"additionalProperties":false,"description":"Patch a track's `name` / `enabled` by id."},{"type":"object","properties":{"type":{"type":"string","const":"reorderTracks"},"fromIndex":{"type":"number"},"toIndex":{"type":"number"}},"required":["type","fromIndex","toIndex"],"additionalProperties":false,"description":"Move a track from one index to another. ORDER: index 0 is the TOP layer, not the bottom — moving a backdrop to index 0 puts it in FRONT of everything and hides the composition. Higher index = further back. PRECEDENCE: track order decides compositing only among clips on the same plane. Overlays are composited in a lane ABOVE the video lane whatever their track index; the one exception is `zPlane:\"behind-subject\"`, which moves the overlay inside its host clip, behind the segmented foreground. So if reordering tracks does not change what you see, the plane split already decided it."},{"type":"object","properties":{"type":{"type":"string","const":"moveClipToTrack"},"clipId":{"type":"string"},"targetTrackId":{"type":"string"},"newStartTime":{"type":"number"}},"required":["type","clipId","targetTrackId"],"additionalProperties":false,"description":"Move a clip to another SAME-family track, optionally at a new `newStartTime`."},{"type":"object","properties":{"type":{"type":"string","const":"duplicateClip"},"clipId":{"type":"string"},"newClipId":{"type":"string"}},"required":["type","clipId"],"additionalProperties":false,"description":"Duplicate a clip by id. Pin `newClipId` to make the copy's id deterministic (required for a clean undo/inverse)."},{"type":"object","properties":{"type":{"type":"string","const":"cutAndRipple"},"start":{"type":"number"},"end":{"type":"number"}},"required":["type","start","end"],"additionalProperties":false,"description":"Server-authoritative: delete the [start,end] time window (seconds) and ripple every downstream clip/marker/caption earlier to close the gap."},{"type":"object","properties":{"type":{"type":"string","const":"ripple"},"time":{"type":"number"},"amount":{"type":"number"}},"required":["type","time","amount"],"additionalProperties":false,"description":"Server-authoritative: shift everything at/after `time` (seconds) by `amount` seconds (+ opens a gap, − closes one)."},{"type":"object","properties":{"type":{"type":"string","const":"addExcludedRange"},"clipId":{"type":"string"},"sourceStart":{"type":"number"},"sourceEnd":{"type":"number"},"reason":{"type":"string"}},"required":["type","clipId","sourceStart","sourceEnd"],"additionalProperties":false,"description":"Server-authoritative: exclude a [sourceStart,sourceEnd] span (seconds) of a clip's SOURCE (an internal trim) and ripple downstream — the preferred way to drop a sub-range vs a source patch."},{"type":"object","properties":{"type":{"type":"string","const":"removeExcludedRange"},"clipId":{"type":"string"},"rangeIdx":{"type":"number"}},"required":["type","clipId","rangeIdx"],"additionalProperties":false,"description":"Server-authoritative: remove a clip's previously-added excluded range by index (re-includes that span, ripples downstream)."},{"type":"object","properties":{"type":{"type":"string","const":"component.repin"},"componentId":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"}},"required":["type","componentId","from","to"],"additionalProperties":false,"description":"Move every pin of a component at version `from` to version `to`: the clips that place it and the scene surfaces that nest it. A clip's version changes only through a composition write; a component edit issues this op over the composition it names."},{"type":"object","properties":{"type":{"type":"string","const":"component.repin-v3"},"componentId":{"type":"string","minLength":1},"from":{"type":"string","pattern":"^[a-f0-9]{64}$"},"to":{"type":"string","pattern":"^[a-f0-9]{64}$"},"expectedCompositionEtag":{"type":"string","minLength":1},"changes":{"minItems":1,"maxItems":512,"type":"array","items":{"type":"object","properties":{"placementId":{"type":"string","minLength":1},"before":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false},"after":{"type":"object","properties":{"version":{"type":"number","const":3},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"params":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/ComponentParameterValue"}},"seed":{"type":"string","minLength":1},"assets":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":256},"additionalProperties":{"type":"string","minLength":1,"maxLength":256}},"mediaBindings":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":128},"additionalProperties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":128}}}},"required":["version","componentId","sourceVersionId","params","seed"],"additionalProperties":false}},"required":["placementId","before","after"],"additionalProperties":false}}},"required":["type","componentId","from","to","expectedCompositionEtag","changes"],"additionalProperties":false,"description":"Atomically repin explicit version3 invocations using complete before/after execution references and an exact composition etag. Persistence must canonically admit scoped source hashes, destination input schemas and every resulting target context before applying, including replay/undo. Never infer a latest head, downgrade versions or accept an admitted flag."}],"description":"One scoped composition operation. Discriminated by `type` — `clip.add` / `clip.remove` / `clip.update` patch clips across any family; the rest cover markers, reframe, effects, captions, format, tracks, and the server-authoritative ripple recomputes. Every variant is `.strict()`: an unknown field is refused, not ignored.","type":"object"},"SceneShotSpecV2":{"type":"object","properties":{"version":{"type":"number","const":2},"referenceSize":{"type":"object","properties":{"width":{"type":"integer","minimum":16,"maximum":8192},"height":{"type":"integer","minimum":16,"maximum":8192}},"required":["width","height"],"additionalProperties":false},"camera":{"type":"object","properties":{"position":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"fov":{"type":"number","minimum":0.3141592653589793,"maximum":1.3962634015954636}},"additionalProperties":false},"environment":{"default":{"lightingProfile":"studio","preset":"soft","intensity":1,"floorY":-420,"shadowOpacity":0.5},"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"studio"},"lightingProfile":{"default":"studio","type":"string","enum":["studio","studio-edge"]},"preset":{"default":"soft","type":"string","enum":["soft","key","rim"]},"intensity":{"default":1,"type":"number","minimum":0},"floorY":{"default":-420,"type":"number"},"shadowOpacity":{"default":0.5,"type":"number","minimum":0,"maximum":1}},"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"photographic-studio-v1"}},"required":["kind"],"additionalProperties":false}]},"backdrop":{"default":{"kind":"transparent"},"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"transparent"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"solid"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["kind","color"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"linear"},"angle":{"default":0,"type":"number"},"stops":{"minItems":2,"maxItems":8,"type":"array","items":{"type":"object","properties":{"at":{"type":"number","minimum":0,"maximum":1},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["at","color"],"additionalProperties":false}}},"required":["kind","stops"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"radial"},"at":{"default":[0.5,0.5],"type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}],"items":false,"minItems":2,"maxItems":2},"stops":{"minItems":2,"maxItems":8,"type":"array","items":{"type":"object","properties":{"at":{"type":"number","minimum":0,"maximum":1},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["at","color"],"additionalProperties":false}}},"required":["kind","stops"],"additionalProperties":false}]},"layers":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/__schema0"}},"animation":{"default":[],"type":"array","items":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"camera"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"layer"},"layerId":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"}},"required":["kind","layerId"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"environment"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"focus"}},"required":["kind"],"additionalProperties":false}]},"property":{"type":"string","enum":["positionX","positionY","positionZ","rotationX","rotationY","rotationZ","fov","scale","opacity","openAngle","x","y","rotation","intensity","distance","range","maxBlur"]},"keyframes":{"minItems":1,"maxItems":256,"type":"array","items":{"type":"object","properties":{"at":{"type":"number","minimum":0,"maximum":1},"value":{"type":"number"},"easing":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"linear"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"hold"}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"bezier"},"x1":{"type":"number","minimum":0,"maximum":1},"y1":{"type":"number","minimum":-4,"maximum":5},"x2":{"type":"number","minimum":0,"maximum":1},"y2":{"type":"number","minimum":-4,"maximum":5}},"required":["kind","x1","y1","x2","y2"],"additionalProperties":false}]}},"required":["at","value"],"additionalProperties":false}}},"required":["target","property","keyframes"],"additionalProperties":false}},"post":{"default":{"grain":0,"vignette":0,"focus":null},"type":"object","properties":{"grain":{"default":0,"type":"number","minimum":0,"maximum":0.5},"vignette":{"default":0,"type":"number","minimum":0,"maximum":1},"focus":{"default":null,"anyOf":[{"type":"object","properties":{"distance":{"type":"number","exclusiveMinimum":0},"range":{"type":"number","exclusiveMinimum":0},"maxBlur":{"type":"number","minimum":0,"maximum":64}},"required":["distance","range","maxBlur"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"constraints":{"default":[],"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","const":"minSeparation"},"objects":{"minItems":2,"type":"array","items":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"}},"gap":{"type":"number","exclusiveMinimum":0}},"required":["kind","objects","gap"],"additionalProperties":false}}},"required":["version","referenceSize","layers"],"additionalProperties":false,"description":"A version-2 scene shot: a self-contained 3D world-object shot that scene.add / scene.update materializes into an ordinary component clip. The shot owns its layers, camera, lighting, backdrop and normalized local animation; the composition owns start, duration, ordering, cuts and transitions. Coordinates are REFERENCE PIXELS: origin at frame centre, +X right, +Y down, +Z toward the viewer. referenceSize must have the SAME aspect ratio as the composition format; mismatch fails instead of cropping. At equal aspect ratio the shot scales uniformly by outputWidth/referenceWidth. A segment's easing belongs to the keyframe it ARRIVES at; the first keyframe has no easing. Authoring limits: 32 layers, 4 devices, 16 distinct image slots, 256 keyframes per channel, 2048 keyframes per shot. Version 2 supports nested groups, procedural slab/page/phone/laptop objects, screen- and world-space text, admitted image/component/video surfaces, fixed photographic and generated studio environments, transparent/solid/linear/radial backdrops, constraints, focus, grain and vignette. Raw HTML, custom shader props, imported GLB models, arbitrary external HDR environments, skeletal animation and physics are refused with an exact field path."},"TransitionSpec":{"type":"object","properties":{"type":{"type":"string","enum":["cut","fade","dissolve","wipe"]},"duration":{"type":"number","minimum":0}},"required":["type"],"additionalProperties":false,"description":"Inter-scene transition."},"__schema0":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"group"},"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"children":{"minItems":1,"maxItems":16,"type":"array","items":{"$ref":"#/components/schemas/__schema0"}}},"required":["kind","id","children"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"laptop"},"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":200,"maximum":4000},"openAngle":{"type":"number","minimum":0,"maximum":3.141592653589793},"materials":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"role":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["physical","unlit"]},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"roughness":{"type":"number","minimum":0,"maximum":1},"metalness":{"type":"number","minimum":0,"maximum":1},"clearcoat":{"type":"number","minimum":0,"maximum":1},"clearcoatRoughness":{"type":"number","minimum":0,"maximum":1},"anisotropy":{"type":"number","minimum":0,"maximum":1},"anisotropyRotation":{"type":"number"},"ior":{"type":"number","minimum":1,"maximum":2.333},"reflectivity":{"type":"number","minimum":0,"maximum":1}},"required":["role","type"],"additionalProperties":false}},"surfaces":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"image"},"assetSlot":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$","description":"Image asset slot name bound by the clip assets map; never a URL."}},"required":["source","assetSlot"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"color"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["source","color"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"component"},"component":{"type":"object","properties":{"version":{"type":"number","const":1},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["version","componentId","sourceVersionId"],"additionalProperties":false},"captureFrame":{"type":"integer","minimum":0,"maximum":9007199254740991},"layout":{"type":"object","properties":{"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["width","height"],"additionalProperties":false},"bakeScale":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}],"description":"Optional authored scale. Preparation defaults omission to 2 and may auto-raise it to 3."},"params":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"$ref":"#/components/schemas/__schema1"}}},"required":["source","component","captureFrame","layout"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"video"},"mediaId":{"type":"string","minLength":1,"maxLength":256},"startFrame":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991},"endFrame":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["source","mediaId"],"additionalProperties":false}]}}},"required":["kind","id","width","openAngle"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"phone"},"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":80,"maximum":2000},"materials":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"role":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["physical","unlit"]},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"roughness":{"type":"number","minimum":0,"maximum":1},"metalness":{"type":"number","minimum":0,"maximum":1},"clearcoat":{"type":"number","minimum":0,"maximum":1},"clearcoatRoughness":{"type":"number","minimum":0,"maximum":1},"anisotropy":{"type":"number","minimum":0,"maximum":1},"anisotropyRotation":{"type":"number"},"ior":{"type":"number","minimum":1,"maximum":2.333},"reflectivity":{"type":"number","minimum":0,"maximum":1}},"required":["role","type"],"additionalProperties":false}},"surfaces":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"image"},"assetSlot":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$","description":"Image asset slot name bound by the clip assets map; never a URL."}},"required":["source","assetSlot"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"color"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["source","color"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"component"},"component":{"type":"object","properties":{"version":{"type":"number","const":1},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["version","componentId","sourceVersionId"],"additionalProperties":false},"captureFrame":{"type":"integer","minimum":0,"maximum":9007199254740991},"layout":{"type":"object","properties":{"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["width","height"],"additionalProperties":false},"bakeScale":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}],"description":"Optional authored scale. Preparation defaults omission to 2 and may auto-raise it to 3."},"params":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"$ref":"#/components/schemas/__schema1"}}},"required":["source","component","captureFrame","layout"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"video"},"mediaId":{"type":"string","minLength":1,"maxLength":256},"startFrame":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991},"endFrame":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["source","mediaId"],"additionalProperties":false}]}}},"required":["kind","id","width"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"slab"},"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":40,"maximum":8000},"height":{"type":"number","minimum":40,"maximum":8000},"thickness":{"default":32,"type":"number","minimum":4,"maximum":200},"cornerRadius":{"default":32,"type":"number","minimum":0},"edgeRadius":{"default":15,"type":"number","minimum":0},"finish":{"default":"satin","type":"string","enum":["satin","brushed"]},"materials":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"role":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["physical","unlit"]},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"roughness":{"type":"number","minimum":0,"maximum":1},"metalness":{"type":"number","minimum":0,"maximum":1},"clearcoat":{"type":"number","minimum":0,"maximum":1},"clearcoatRoughness":{"type":"number","minimum":0,"maximum":1},"anisotropy":{"type":"number","minimum":0,"maximum":1},"anisotropyRotation":{"type":"number"},"ior":{"type":"number","minimum":1,"maximum":2.333},"reflectivity":{"type":"number","minimum":0,"maximum":1}},"required":["role","type"],"additionalProperties":false}},"surfaces":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"image"},"assetSlot":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$","description":"Image asset slot name bound by the clip assets map; never a URL."}},"required":["source","assetSlot"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"color"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["source","color"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"component"},"component":{"type":"object","properties":{"version":{"type":"number","const":1},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["version","componentId","sourceVersionId"],"additionalProperties":false},"captureFrame":{"type":"integer","minimum":0,"maximum":9007199254740991},"layout":{"type":"object","properties":{"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["width","height"],"additionalProperties":false},"bakeScale":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}],"description":"Optional authored scale. Preparation defaults omission to 2 and may auto-raise it to 3."},"params":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"$ref":"#/components/schemas/__schema1"}}},"required":["source","component","captureFrame","layout"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"video"},"mediaId":{"type":"string","minLength":1,"maxLength":256},"startFrame":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991},"endFrame":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["source","mediaId"],"additionalProperties":false}]}}},"required":["kind","id","width","height"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"page"},"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"width":{"type":"number","minimum":40,"maximum":8000},"height":{"type":"number","minimum":40,"maximum":8000},"fit":{"default":"contain","type":"string","enum":["contain","cover"]},"transparency":{"default":"straight","type":"string","enum":["straight","premultiplied","opaque"]},"depthWrite":{"default":true,"type":"boolean"},"backface":{"default":"hidden","type":"string","enum":["hidden","visible"]},"materials":{"maxItems":16,"type":"array","items":{"type":"object","properties":{"role":{"type":"string","minLength":1,"maxLength":64},"type":{"type":"string","enum":["physical","unlit"]},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"roughness":{"type":"number","minimum":0,"maximum":1},"metalness":{"type":"number","minimum":0,"maximum":1},"clearcoat":{"type":"number","minimum":0,"maximum":1},"clearcoatRoughness":{"type":"number","minimum":0,"maximum":1},"anisotropy":{"type":"number","minimum":0,"maximum":1},"anisotropyRotation":{"type":"number"},"ior":{"type":"number","minimum":1,"maximum":2.333},"reflectivity":{"type":"number","minimum":0,"maximum":1}},"required":["role","type"],"additionalProperties":false}},"surfaces":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"image"},"assetSlot":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z_][A-Za-z0-9_-]*$","description":"Image asset slot name bound by the clip assets map; never a URL."}},"required":["source","assetSlot"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"color"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]}},"required":["source","color"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"component"},"component":{"type":"object","properties":{"version":{"type":"number","const":1},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["version","componentId","sourceVersionId"],"additionalProperties":false},"captureFrame":{"type":"integer","minimum":0,"maximum":9007199254740991},"layout":{"type":"object","properties":{"width":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"height":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["width","height"],"additionalProperties":false},"bakeScale":{"anyOf":[{"type":"number","const":2},{"type":"number","const":3}],"description":"Optional authored scale. Preparation defaults omission to 2 and may auto-raise it to 3."},"params":{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"$ref":"#/components/schemas/__schema1"}}},"required":["source","component","captureFrame","layout"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"video"},"mediaId":{"type":"string","minLength":1,"maxLength":256},"startFrame":{"default":0,"type":"integer","minimum":0,"maximum":9007199254740991},"endFrame":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["source","mediaId"],"additionalProperties":false}]}}},"required":["kind","id","width","height","surfaces"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"kind":{"type":"string","const":"text"},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"lines":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"object","properties":{"runs":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":512,"pattern":"^[^\\r\\n]+$"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"emphasis":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["runs"],"additionalProperties":false}},"fontFamily":{"anyOf":[{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _.\\-]*$"},{"type":"string","enum":["$brand:fonts.heading","$brand:fonts.body","$brand:fonts.caption"]}]},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"fontStyle":{"type":"string","enum":["normal","italic"]},"fontSize":{"type":"number","minimum":8,"maximum":800},"lineHeight":{"default":1.2,"type":"number","minimum":0.6,"maximum":3},"letterSpacing":{"default":0,"type":"number","minimum":-20,"maximum":40},"align":{"default":"center","type":"string","enum":["left","center","right"]},"maxWidth":{"type":"number","exclusiveMinimum":0},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"space":{"type":"string","const":"world"},"transform":{"default":{"position":[0,0,0],"rotation":[0,0,0],"scale":1},"type":"object","properties":{"position":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"rotation":{"default":[0,0,0],"type":"array","prefixItems":[{"type":"number"},{"type":"number"},{"type":"number"}],"items":false,"minItems":3,"maxItems":3},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"additionalProperties":false}},"required":["id","kind","lines","fontFamily","fontWeight","fontStyle","fontSize","color","space"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]*$"},"kind":{"type":"string","const":"text"},"opacity":{"default":1,"type":"number","minimum":0,"maximum":1},"lines":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"object","properties":{"runs":{"minItems":1,"maxItems":16,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":512,"pattern":"^[^\\r\\n]+$"},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"emphasis":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["runs"],"additionalProperties":false}},"fontFamily":{"anyOf":[{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9 _.\\-]*$"},{"type":"string","enum":["$brand:fonts.heading","$brand:fonts.body","$brand:fonts.caption"]}]},"fontWeight":{"type":"integer","minimum":100,"maximum":900},"fontStyle":{"type":"string","enum":["normal","italic"]},"fontSize":{"type":"number","minimum":8,"maximum":800},"lineHeight":{"default":1.2,"type":"number","minimum":0.6,"maximum":3},"letterSpacing":{"default":0,"type":"number","minimum":-20,"maximum":40},"align":{"default":"center","type":"string","enum":["left","center","right"]},"maxWidth":{"type":"number","exclusiveMinimum":0},"color":{"anyOf":[{"type":"string","pattern":"^#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"},{"type":"string","enum":["$brand:colors.background","$brand:colors.surface","$brand:colors.text","$brand:colors.textMuted","$brand:colors.accent","$brand:colors.accentStrong","$brand:colors.accentSoft","$brand:colors.success","$brand:colors.warning","$brand:colors.danger"]}]},"space":{"type":"string","const":"screen"},"x":{"type":"number"},"y":{"type":"number"},"rotation":{"default":0,"type":"number"},"scale":{"default":1,"type":"number","exclusiveMinimum":0}},"required":["id","kind","lines","fontFamily","fontWeight","fontStyle","fontSize","color","space","x","y"],"additionalProperties":false}]},"__schema1":{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"number"},{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/__schema1"}},{"propertyNames":{"type":"string"},"type":"object","properties":{},"additionalProperties":{"$ref":"#/components/schemas/__schema1"}}]},"CompositionCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"format":{"$ref":"#/components/schemas/FormatSpec"}},"additionalProperties":false,"description":"POST /projects/:id/compositions body — create a new video (composition) in the project. `format` defaults to the project's compositionFormat when omitted."},"CompositionDependencyRead":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","const":"guarded"},"basis":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":256},"token":{"type":"string","maxLength":65536}},"required":["key","token"],"additionalProperties":false}},"absentClipToken":{"type":"string","const":"null"}},"required":["mode","basis","absentClipToken"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"exact"},"reason":{"type":"string"}},"required":["mode","reason"],"additionalProperties":false}]},"CompositionFromSuggestionRequest":{"type":"object","properties":{"suggestionId":{"type":"string","minLength":1},"format":{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false}},"required":["suggestionId"],"additionalProperties":false,"example":{"suggestionId":"sug_01J8Z3K9Q2X4Y5W6V7T8R9S0P1"}},"CompositionListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompositionSummary"}}},"required":["data"],"additionalProperties":false,"description":"GET /projects/:id/compositions response."},"CompositionSummary":{"type":"object","properties":{"compositionId":{"type":"string"},"format":{"$ref":"#/components/schemas/FormatSpec"},"etag":{"type":"string"},"isActive":{"type":"boolean"},"updatedAt":{"type":"number"},"sceneCount":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["compositionId","format","etag","isActive","updatedAt","sceneCount"],"additionalProperties":false,"description":"A composition in a project, flagging the active one."},"CompositionReadResponse":{"anyOf":[{"$ref":"#/components/schemas/Composition"},{"type":"object","properties":{"composition":{"$ref":"#/components/schemas/Composition"},"composition_id":{"type":"string"},"revision":{"type":"integer","minimum":0,"maximum":9007199254740991},"dependencies":{"$ref":"#/components/schemas/CompositionDependencyRead"},"expectedBrandIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"brandAuthorityError":{"type":"string"}},"required":["composition","composition_id","revision","dependencies"],"additionalProperties":false}]},"CompositionReplaceRequest":{"anyOf":[{"type":"object","properties":{"composition":{"$ref":"#/components/schemas/Composition"},"componentExecutionVersions":{"minItems":1,"maxItems":1,"type":"array","items":{"type":"number","const":3}},"builtinSources":{"minItems":1,"maxItems":512,"type":"array","items":{"type":"object","properties":{"scope":{"type":"object","properties":{"kind":{"type":"string","const":"builtin"},"collection":{"type":"string","minLength":1,"maxLength":256}},"required":["kind","collection"],"additionalProperties":false},"componentId":{"type":"string","minLength":1,"maxLength":256},"sourceVersionId":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceVersion":{"type":"number","const":3}},"required":["scope","componentId","sourceVersionId","sourceVersion"],"additionalProperties":false}},"expectedBrandIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["composition","componentExecutionVersions"],"additionalProperties":false},{"$ref":"#/components/schemas/Composition"}],"examples":[{"composition":{"v":1,"format":{"aspectRatio":"16:9","fps":30},"tracks":[]},"componentExecutionVersions":[3],"expectedBrandIdentity":"0000000000000000000000000000000000000000000000000000000000000000"}]},"ConsultRequest":{"type":"object","properties":{"intent":{"type":"string","minLength":1,"maxLength":2000,"description":"Plain-English goal — what you're trying to achieve with this edit."},"mode":{"description":"advise = proposer-only (no render/judge, no grounded assessment); amend (default) = grade the current composition + author the fix for the weakest criterion; explore = ranked slate of diverse directions. All modes are async — poll the returned job.","type":"string","enum":["advise","amend","explore"]},"focus":{"description":"Optional criterion to concentrate the advice on.","type":"string","enum":["editorial","spatial","brand","caption"]},"ifMatch":{"description":"Etag of the composition the advice is computed against. Proposals are bound to it; apply a proposal BEFORE any other edit or it will 409.","type":"string"}},"required":["intent"],"additionalProperties":false,"description":"POST /projects/:id/consult body."},"ConsultResponse":{"type":"object","properties":{"consultJobId":{"type":"string","description":"Opaque consult job id; poll it for the advisory result."},"projectId":{"type":"string"},"status":{"type":"string","enum":["queued","failed"],"description":"queued = normal; failed = startup failed and the job is already terminal."},"streamUrl":{"description":"Relative SSE endpoint to stream this job's events.","type":"string"}},"required":["consultJobId","projectId","status"],"additionalProperties":false,"description":"POST /projects/:id/consult response."},"CriticCreateRequest":{"type":"object","properties":{"criticId":{"type":"string","minLength":1,"description":"Stable client id; re-registering the same id UPSERTS."},"label":{"type":"string","minLength":1},"tier":{"type":"string","enum":["rules","rubric","evaluator"]},"floor":{"description":"Score below this routes a refine like a built-in criterion. Defaults to 6.","type":"number","minimum":0,"maximum":10},"rules":{"description":"tier \"rules\": declarative ClientRule[] (data).","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"rubric":{"description":"tier \"rubric\": your criterion + description; scored as an extra column.","type":"string"},"referenceMediaIds":{"description":"tier \"rubric\"/\"evaluator\": up to 6 org media ids whose thumbnails the judge sees as YOUR reference standard — \"looks like mine\" becomes a machine check. Each must be an org-owned media item with a visual thumbnail (422 names any that is not).","maxItems":6,"type":"array","items":{"type":"string"}},"url":{"description":"tier \"evaluator\": your HTTPS webhook; CueFrame POSTs the artifact.","type":"string","format":"uri"}},"required":["criticId","label","tier"],"additionalProperties":false,"description":"Register a custom compose critic."},"CriticListResponse":{"type":"object","properties":{"critics":{"type":"array","items":{"$ref":"#/components/schemas/CriticSummary"}}},"required":["critics"],"additionalProperties":false},"CriticSummary":{"type":"object","properties":{"criticId":{"type":"string"},"label":{"type":"string"},"tier":{"type":"string","enum":["rules","rubric","evaluator"]},"floor":{"type":"number"},"referenceMediaIds":{"type":"array","items":{"type":"string"}}},"required":["criticId","label","tier","floor"],"additionalProperties":false,"description":"One registered critic (rubric/rules/url stay write-only — never echoed)."},"CriticResponse":{"type":"object","properties":{"id":{"type":"string"},"criticId":{"type":"string"},"tier":{"type":"string","enum":["rules","rubric","evaluator"]},"secret":{"description":"evaluator tier: Standard-Webhooks signing secret, returned ONCE.","type":"string"}},"required":["id","criticId","tier"],"additionalProperties":false,"description":"POST /critics response (evaluator secret present exactly once)."},"DeriveCompositionRequest":{"type":"object","properties":{"fromCompositionId":{"type":"string","minLength":1,"description":"Source composition to reframe a sibling from."},"targetFormat":{"description":"The target output format (aspectRatio + optional fps/resolution) for the new sibling.","$ref":"#/components/schemas/FormatSpec"}},"required":["fromCompositionId","targetFormat"],"additionalProperties":false,"description":"Derive a reframed sibling composition for a new aspect (Auto-Reframe / Magic-Resize, agent-native)."},"DeriveCompositionResponse":{"type":"object","properties":{"compositionId":{"type":"string","description":"The new sibling composition's id."}},"required":["compositionId"],"additionalProperties":false,"description":"POST /projects/:id/compositions/derive response."},"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable error code per §Error Model."},"message":{"type":"string","description":"Human-readable message."},"contract":{"type":"string","description":"Contract version that produced this verdict. If it differs between two calls, the rules changed underneath you, not your request."},"contractVersion":{"type":"string","description":"Version of the published `@cueframe/api-contract` this server implements. Compare it with the `contractVersion` of the package your client was generated from: a higher value here means the server has moved ahead of your document."},"details":{"description":"Optional context (currentEtag, projectIds, retryAfter, …).","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","message","contract","contractVersion"],"description":"Standard API error envelope."}},"required":["error"],"description":"Error envelope used by every non-2xx response."},"ExactMediaFactResolution":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["subjectTrack","matte"]},"scope":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["startSec","endSec"],"additionalProperties":false},"state":{"type":"string","enum":["pending","ready","failed"]},"fact":{"$ref":"#/components/schemas/MediaFact"}},"required":["kind","scope","state","fact"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["subjectTrack","matte"]},"scope":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["startSec","endSec"],"additionalProperties":false},"state":{"type":"string","enum":["available","unavailable"]},"offer":{"$ref":"#/components/schemas/MediaFactOffer"}},"required":["kind","scope","state","offer"],"additionalProperties":false}],"description":"The server-selected fact or offer for one exact source window. Present when kind, startSec, and endSec are supplied; clients consume this instead of recreating the fact hash.","type":"object"},"MediaFact":{"type":"object","properties":{"kind":{"type":"string","enum":["transcript","subjectTrack","matte"]},"intent":{"type":"object","properties":{"kind":{"type":"string","enum":["whole","window"]},"window":{"description":"The SOURCE window this fact covers, when it is scoped to a clip.","type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["startSec","endSec"],"additionalProperties":false}},"required":["kind"],"additionalProperties":false},"status":{"type":"string","enum":["pending","ready","failed"]},"summary":{"type":"object","properties":{"presenceFraction":{"description":"Matte only: fraction of frames carrying a detected subject (0–1). Below 0.6 there is no reliable silhouette — the matte is delivered but cannot carry a behind-subject graphic, and is NOT charged.","type":"number"},"faceCount":{"type":"number"},"language":{"type":"string"},"wordCount":{"type":"number"},"durationSec":{"type":"number"}},"additionalProperties":false},"charge":{"description":"What this fact was BILLED, in USD. Absent when it cost nothing: a compose/render side effect (already paid for inside that operation) or an unusable matte.","type":"object","properties":{"usd":{"type":"number"}},"required":["usd"],"additionalProperties":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"readyAt":{"type":"number"}},"required":["kind","intent","status"],"additionalProperties":false,"description":"One derived fact about a media item — computed once, charged at most once."},"MediaFactOffer":{"type":"object","properties":{"kind":{"type":"string","enum":["transcript","subjectTrack","matte"]},"quotedUsd":{"type":"number","description":"The server's price for this enhancement, in USD. Meaningful ONLY when `available` is true — an unavailable offer quotes 0 because there is nothing to price yet."},"available":{"type":"boolean"},"reason":{"description":"Why this cannot be bought right now. Present iff `available` is false. e.g. `media_not_ready` (the source has no known duration yet).","type":"string"}},"required":["kind","quotedUsd","available"],"additionalProperties":false,"description":"A purchasable enhancement that this media item does not have yet."},"ExemplarUploadsRequest":{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":24},"contentType":{"type":"string","enum":["image/jpeg","image/png"]},"includeContactSheet":{"type":"boolean"}},"required":["count"],"additionalProperties":false,"description":"POST /brand-kits/exemplar-uploads body. Reserve presigned PUT slots for curated reference frames (≤720px recommended — they are vision input tokens downstream)."},"ExemplarUploadsResponse":{"type":"object","properties":{"batchId":{"type":"string"},"uploads":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"url":{"type":"string"}},"required":["key","url"],"additionalProperties":false}},"contactSheetUpload":{"type":"object","properties":{"key":{"type":"string"},"url":{"type":"string"}},"required":["key","url"],"additionalProperties":false},"expiresAt":{"type":"string"}},"required":["batchId","uploads","expiresAt"],"additionalProperties":false},"ExportCreateRequest":{"type":"object","properties":{"clipSuggestionId":{"type":"string","minLength":1}},"required":["clipSuggestionId"],"additionalProperties":false,"description":"POST /projects/:id/exports/{fcpxml,premiere} body."},"ExportError":{"type":"object","properties":{"phase":{"type":"string","enum":["trim","build","upload","trigger"]},"message":{"type":"string"},"detail":{"type":"string"},"retryable":{"type":"boolean"}},"required":["phase","message","retryable"],"additionalProperties":false},"ExportFormat":{"type":"string","enum":["fcpxml","premiere"]},"ExportResponse":{"type":"object","properties":{"id":{"type":"string"},"format":{"$ref":"#/components/schemas/ExportFormat"},"status":{"$ref":"#/components/schemas/ExportStatus"},"progress":{"type":"number","minimum":0,"maximum":1,"description":"Fractional progress 0..1 across the trim/build/upload pipeline. Reaches 1 only on `complete`."},"outputUrl":{"type":["string","null"]},"outputExpiresAt":{"type":["string","null"]},"outputSizeBytes":{"type":["number","null"]},"outputDurationSec":{"type":["number","null"]},"error":{"anyOf":[{"$ref":"#/components/schemas/ExportError"},{"type":"null"}],"description":"Set when status is `error`; null otherwise. The phase field localizes the failure to trim / build / upload / trigger."},"trimCacheHit":{"type":["boolean","null"]},"clipSuggestionId":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","format","status","progress","outputUrl","outputExpiresAt","outputSizeBytes","outputDurationSec","error","trimCacheHit","clipSuggestionId","createdAt","updatedAt"],"additionalProperties":false,"description":"NLE export job response."},"ExportStatus":{"type":"string","enum":["queued","trimming","building","uploading","complete","error","cancelled"]},"ExtractBrandKitRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"],"additionalProperties":false,"description":"POST /brand-kits/extract body — the website URL to extract brand tokens from."},"ExtractBrandKitResponse":{"type":"object","properties":{"colors":{"type":"array","items":{"type":"string"}},"fonts":{"type":"array","items":{"type":"string"}},"title":{"type":"string"},"description":{"type":"string"}},"required":["colors","fonts"],"additionalProperties":false,"description":"POST /brand-kits/extract response — extracted brand tokens (not persisted)."},"FontSearchRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200},"perPage":{"type":"integer","exclusiveMinimum":0,"maximum":50}},"required":["query"],"additionalProperties":false,"description":"POST /fonts/search body."},"FontSearchResponse":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"family":{"type":"string"},"category":{"type":"string"},"variants":{"type":"array","items":{"type":"string"}},"cssUrl":{"type":"string"},"previewText":{"type":"string"}},"required":["family"],"additionalProperties":false}}},"required":["results"],"additionalProperties":false,"description":"POST /fonts/search response."},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"]},"version":{"type":"string"},"checks":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"ok":{"type":"boolean"},"detail":{"type":"string"}},"required":["ok"],"additionalProperties":false}}},"required":["status","version"],"additionalProperties":false,"description":"Health probe response."},"JobEnqueueResponse":{"type":"object","properties":{"jobId":{"type":"string","description":"Poll GET /v1/jobs/{jobId} / wait_job until terminal."},"jobKey":{"type":"string","description":"Deterministic identity of the work (content hash of every input the result depends on). Re-enqueueing the same key returns the same job while it runs; a failed key revives as a fresh attempt."},"kind":{"type":"string","description":"Job family, e.g. `verify` | `preview` | `brand_kit_extract`."},"status":{"type":"string","enum":["running","succeeded","cancelled"],"description":"running on a fresh/deduped enqueue; succeeded when an identical request already completed. Cancelled is part of the shared status vocabulary; identical cancelled work revives to running."}},"required":["jobId","jobKey","kind","status"],"additionalProperties":false},"JobResponse":{"type":"object","properties":{"id":{"type":"string","description":"Job id — pass to GET /v1/jobs/{id} / wait_job."},"jobKey":{"type":"string","description":"Deterministic identity of the work (idempotency key, e.g. `verify-<sessionId>-<contentHash>` — the hash covers the composition AND grading inputs). Re-enqueueing the same key returns the same job while it runs."},"kind":{"type":"string","description":"Job family, e.g. `verify`."},"status":{"type":"string","enum":["running","succeeded","failed","cancelled"],"description":"Poll until terminal (`succeeded` | `failed` | `cancelled`)."},"progress":{"anyOf":[{"type":"object","properties":{"phase":{"type":"string"},"percent":{"type":"number"},"message":{"type":"string"}},"required":["phase"],"additionalProperties":false},{"type":"null"}],"description":"Executor heartbeat while running; null when none reported."},"result":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/PreviewFrameJobResult"},{"$ref":"#/components/schemas/ComponentPreviewJobResult"},{"$ref":"#/components/schemas/VerifyJobResult"},{"$ref":"#/components/schemas/ExtractBrandKitResponse"}]},{"type":"null"}],"description":"Kind-specific payload when status is `succeeded`; null otherwise."},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}],"description":"Stable failure code + human message when status is `failed`; null otherwise. `job_timeout` = the executor died mid-run and the stall sweep reaped the job — re-enqueue to retry."},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"completedAt":{"type":["string","null"]}},"required":["id","jobKey","kind","status","progress","result","error","createdAt","updatedAt","completedAt"],"additionalProperties":false},"PreviewFrameJobResult":{"type":"object","properties":{"geometry":{"type":"object","properties":{"scale":{"type":"number"},"compositionWidth":{"type":"number"},"compositionHeight":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"}},"required":["scale"],"additionalProperties":false},"warnings":{"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"previewed":{"type":"object","properties":{"source":{"type":"string","enum":["inline","scratch","persisted"]},"compositionId":{"type":"string"},"etag":{"type":"string"}},"required":["source"],"additionalProperties":false},"listUsd":{"description":"List price charged for this delivered capture.","type":"number"},"artifacts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"beatSec":{"type":"number"},"bytes":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"contentType":{"type":"string","enum":["image/png","image/jpeg"]},"layers":{"type":"object","properties":{"video":{"type":["string","null"]},"overlays":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["video","overlays"],"additionalProperties":false},"url":{"type":"string","format":"uri"},"urlExpiresAt":{"type":"string"}},"required":["id","beatSec","bytes","contentType","layers","url","urlExpiresAt"],"additionalProperties":false}}},"required":["geometry","previewed","artifacts"],"additionalProperties":false},"VerifyJobResult":{"type":"object","properties":{"perCriterion":{},"composite":{"type":"number"},"critique":{"type":"string"},"checkpointId":{"type":"string"},"beats":{},"clientScores":{"type":"array","items":{}},"listUsd":{"description":"List price charged for this delivered evaluation.","type":"number"}},"required":["perCriterion","composite","critique","checkpointId"],"additionalProperties":false},"LibrarySearchResponse":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/LibrarySearchResult"},"description":"Matching moments, best first. Empty means nothing matched (when `indexing` is false) — the library was searched and came back empty-handed."},"indexing":{"type":"boolean","description":"TRUE when some of the org's footage is NOT in the visual index yet — media that predates it, or is still processing. This is COVERAGE, not emptiness: it can be true ALONGSIDE results, and then it means \"these are the best moments among what we have looked at so far\", not \"these are the best moments\". An empty `results` with `indexing: true` means \"not looked at yet\", NOT \"no match\" — re-run the media through processing (reprocess) to index it, then search again. FALSE with empty `results` is a real miss: the library was searched and nothing matched."}},"required":["results","indexing"],"additionalProperties":false,"description":"Semantic search over the org's OWN footage. The query is embedded with the same CLIP model that embedded every indexed frame, so a description of what you want to SEE (\"wide shot of the speaker at a whiteboard\") finds the moment even when nobody says those words."},"LibrarySearchResult":{"type":"object","properties":{"mediaId":{"type":"string","description":"The media item this moment belongs to — feed it to apply_composition as a clip source, or GET /v1/media/{id}/context for its faces/beat/word grids."},"name":{"type":"string","description":"The media item's name, so a result is readable without a second call."},"score":{"type":"number","description":"Cosine similarity between the query text and the chunk's frame, in [-1, 1]. Higher is closer. Compare scores WITHIN one response; absolute values are not calibrated across queries."},"startSec":{"type":"number","description":"Moment start, SECONDS from the media item's start."},"endSec":{"type":"number","description":"Moment end, SECONDS from the media item's start."},"thumbUrl":{"description":"Presigned URL for the media item's thumbnail, or null when it has none. This is the ITEM's thumbnail, not a still of this moment — render a still of the exact range with preview_frame.","type":["string","null"]}},"required":["mediaId","name","score","startSec","endSec","thumbUrl"],"additionalProperties":false},"MatteBakeRequest":{"type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Source-in of the window to matte, in seconds into the underlying source."},"endSec":{"type":"number","exclusiveMinimum":0,"description":"Source-out of the window to matte, in seconds into the underlying source."}},"required":["startSec","endSec"],"additionalProperties":false,"description":"POST /media/:id/matte body. The window is REQUIRED and is the clip's SOURCE trim, not timeline time: a matte's cost scales with its duration, so there is no whole-source default to fall back on."},"MatteBakeTriggerResponse":{"type":"object","properties":{"factId":{"type":"string"},"status":{"type":"string","enum":["pending","ready","failed"]},"quotedUsd":{"type":"number","description":"The server's price for this matte, in USD, quoted from the window duration."},"alreadyExisted":{"type":"boolean","description":"True when a matte for this exact window was already pending or ready. Nothing was dispatched and nothing will be charged."}},"required":["factId","status","quotedUsd","alreadyExisted"],"additionalProperties":false,"description":"POST /media/:id/matte response — the claimed matte fact."},"MediaContextResponse":{"type":"object","properties":{"mediaId":{"type":"string"},"durationSec":{"type":["number","null"]},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"thumbnail":{"anyOf":[{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false},{"type":"null"}],"description":"Presigned processing thumbnail (~1 week) — the footage at a glance. For stills at chosen timestamps, use preview_frame with a one-clip composition over this media."},"faces":{"type":"object","properties":{"status":{"type":"string","enum":["ready","not_detected"]},"windows":{"type":"array","items":{"$ref":"#/components/schemas/ContextSubjectWindow"}}},"required":["status","windows"],"additionalProperties":false},"transcript":{"type":"object","properties":{"status":{"type":"string","enum":["ready","not_transcribed","unavailable"]},"data":{"anyOf":[{"$ref":"#/components/schemas/TranscriptResponse"},{"type":"null"}]}},"required":["status","data"],"additionalProperties":false},"beatGrid":{"anyOf":[{"type":"object","properties":{"bpm":{"type":"number"},"beatTimesMs":{"type":"array","items":{"type":"number"},"description":"Beat onset times in MILLISECONDS — divide by 1000 for timeline startTime (composition timeline fields are seconds)."},"confidence":{"type":"number","description":"Rhythmic-periodicity strength (0–1). Trust the grid for cutting when high; a beatless bed reports low."},"method":{"type":"string","enum":["requested-anchored","detected"],"description":"`requested-anchored` = phase-locked to a requested BPM (a generated bed whose prompt named a tempo); `detected` = full beat tracking (import/upload)."}},"required":["bpm","beatTimesMs","confidence","method"],"additionalProperties":false},{"type":"null"}],"description":"The MUSIC-role rhythm grid (audio-substrate MVP). Present only for a music bed that carries a computed beat grid; null otherwise. For a music-driven film, cut on these beats (transition midpoints on beats, risers resolving on downbeats)."},"wordGrid":{"anyOf":[{"type":"object","properties":{"wordTimesMs":{"type":"array","items":{"type":"number"},"description":"Word onset times in MILLISECONDS, in order — divide by 1000 for timeline startTime (composition timeline fields are seconds)."}},"required":["wordTimesMs"],"additionalProperties":false},{"type":"null"}],"description":"The VO-role rhythm grid: word onsets surfaced from the transcript (pure exposure). Present only when a transcript exists; null otherwise. For a VO-driven (narration) film, cut every beat boundary to the voice — the film-spine rule."},"audioRole":{"anyOf":[{"type":"string","enum":["vo","music","sfx","ambience"]},{"type":"null"}],"description":"DECLARED audio role of this asset (audio-substrate P0): 'vo' (narration), 'music' (bed that ducks under speech), 'sfx' (one-shot hit), 'ambience' (a bed that HOLDS under VO — never ducks). Author the clip source's `audioRole` from this. Null for footage/images or an undeclared audio asset."},"envelope":{"anyOf":[{"type":"object","properties":{"envelopeClass":{"type":"string","enum":["transient","sweep","ambient"],"description":"Coarse temporal shape: 'transient' (a sharp one-shot), 'sweep' (a bounded rise/fall over ~0.5–2s), 'ambient' (an unbounded bed)."},"attackMs":{"type":"number"},"spectralCentroidHz":{"type":"number"},"meanVolumeDb":{"type":"number"},"maxVolumeDb":{"type":"number"}},"required":["envelopeClass"],"additionalProperties":false},{"type":"null"}],"description":"Envelope evidence (audio-substrate P0). `envelopeClass` is always present when an envelope exists (the SFX pack carries it); the numeric probe stats are present only when an audio probe has run. Null when no envelope is stored."},"facts":{"type":"array","items":{"$ref":"#/components/schemas/MediaFact"},"description":"Derived facts about this source (subject tracks, mattes): what has been computed, its status, and what it was billed. Same shape as GET /media/{id}/facts."},"offers":{"type":"array","items":{"$ref":"#/components/schemas/MediaFactOffer"},"description":"Enhancements this source does not have yet, with a server quote. Same shape as GET /media/{id}/facts. Mattes are quoted per-window via POST /media/{id}/matte, never here."}},"required":["mediaId","durationSec","width","height","thumbnail","faces","transcript","beatGrid","wordGrid","audioRole","envelope","facts","offers"],"additionalProperties":false,"description":"Read-only authoring context for a source media item: detected face roster + transcript + the temporal grids (beat / word) an agent cuts to, the DECLARED audioRole + envelope of an audio asset, and the paid-enhancement block (facts already computed + offers for what is missing)."},"ContextSubjectWindow":{"type":"object","properties":{"detectorVersion":{"type":"string","description":"Version of the face detector that produced this source-window roster."},"window":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"}},"required":["startSec","endSec"],"additionalProperties":false},"faces":{"type":"array","items":{"$ref":"#/components/schemas/ContextFace"}}},"required":["detectorVersion","window","faces"],"additionalProperties":false},"ContextFace":{"type":"object","properties":{"faceId":{"type":"string"},"bbox":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"}},"required":["x","y","width","height"],"additionalProperties":false},"speakingShare":{"type":"number"}},"required":["faceId","bbox"],"additionalProperties":false},"TranscriptResponse":{"type":"object","properties":{"mediaItemId":{"type":"string"},"language":{"type":["string","null"]},"fullText":{"type":"string"},"utterances":{"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"data":{"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["mediaItemId","language","fullText","utterances"],"additionalProperties":false,"description":"Transcript response."},"MediaDirectUploadResponse":{"type":"object","properties":{"id":{"type":"string"},"uploadUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string"}},"required":["id","uploadUrl","expiresAt"],"additionalProperties":false,"description":"POST /media response: reserved media id + a presigned PUT URL. PUT the raw bytes to uploadUrl (≤ ~5 GiB), then POST /media/:id/finalize."},"MediaFactPurchaseRequest":{"type":"object","properties":{"kind":{"type":"string","enum":["subjectTrack","matte"],"description":"Which enhancement to buy. `transcript` is NOT purchasable here — it is delivered by the transcription pipeline."},"intent":{"description":"The SOURCE window. REQUIRED for `matte` (its cost scales with duration). OPTIONAL for `subjectTrack`: give a clip's source window to buy the track the render looks up for THAT clip, and pay only for its duration; omit it to detect the whole source.","type":"object","properties":{"startSec":{"type":"number","minimum":0},"endSec":{"type":"number","exclusiveMinimum":0}},"required":["startSec","endSec"],"additionalProperties":false}},"required":["kind"],"additionalProperties":false,"description":"POST /media/:id/facts body."},"MediaFactPurchaseResponse":{"type":"object","properties":{"factId":{"type":"string"},"status":{"type":"string","enum":["pending","ready","failed"]},"quotedUsd":{"type":"number"},"alreadyExisted":{"type":"boolean","description":"True when this exact fact was already pending or ready. Nothing was dispatched and nothing will be charged."}},"required":["factId","status","quotedUsd","alreadyExisted"],"additionalProperties":false,"description":"POST /media/:id/facts response."},"MediaFactsResponse":{"type":"object","properties":{"facts":{"type":"array","items":{"$ref":"#/components/schemas/MediaFact"}},"offers":{"type":"array","items":{"$ref":"#/components/schemas/MediaFactOffer"},"description":"What is NOT yet present and could be bought. A `matte` offer appears ONLY when the request carried `startSec`+`endSec` (the clip's SOURCE window) — a matte's price is a function of its duration, so there is no honest whole-source matte quote. `transcript` is never offered: it is produced by the ingest pipeline, not bought here."},"exact":{"$ref":"#/components/schemas/ExactMediaFactResolution"}},"required":["facts","offers"],"additionalProperties":false,"description":"Facts and offers for a media item, plus an exact-window resolution when requested."},"MediaFinalizeRequest":{"type":"object","properties":{"audioRole":{"type":"string","enum":["vo","music","sfx","ambience"],"description":"Declared audio role: 'vo' (narration), 'music' (bed that ducks under speech), 'sfx' (one-shot hit), 'ambience' (a bed that HOLDS under VO — never ducks)."}},"additionalProperties":false,"description":"POST /media/:id/finalize body — optional declared audioRole."},"MediaFinalizeResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["processing","complete"]},"processingPhase":{"type":"string"}},"required":["id","status","processingPhase"],"additionalProperties":false,"description":"POST /media/:id/finalize response: ingest triggered (audio/video → processing) or the item is immediately ready (image/asset → complete)."},"MediaGenerateRequest":{"type":"object","properties":{"generator":{"type":"string","enum":["text-to-video","text-to-image","image-to-video","text-to-music","text-to-speech","text-to-sfx","auto"]},"prompt":{"type":"string","minLength":1,"maxLength":10000},"style":{"description":"Free-form generation parameters, read per generator. All generators honor `aspect` (string) + `durationSec` (number) where applicable. text-to-speech honors `voice` (string; default voice when omitted), `speed` (number 0.7-1.2), `stability` (number 0-1), and `styleExaggeration` (number 0-1 → the endpoint's style exaggeration). Provider and model selection are server-owned and cannot be overridden.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"refs":{"type":"object","properties":{"firstFrameMediaId":{"type":"string"},"lastFrameMediaId":{"type":"string"},"imageMediaIds":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}},"required":["generator","prompt"],"additionalProperties":false,"description":"POST /media/generate body."},"MediaGenerateResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","const":"generating"},"estimateUsd":{"type":"number"}},"required":["id","status"],"additionalProperties":false,"description":"POST /media/generate response."},"MediaImportRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"filename":{"type":"string","minLength":1,"maxLength":500},"contentType":{"type":"string","enum":["video/mp4","video/quicktime","video/x-matroska","video/webm","audio/mpeg","audio/wav","audio/x-wav","audio/mp4","audio/aac","image/png","image/jpeg","image/webp","image/gif","image/svg+xml","application/json","font/ttf","font/otf","font/woff","font/woff2"]},"size":{"type":"integer","exclusiveMinimum":0,"maximum":10737418240},"audioRole":{"type":"string","enum":["vo","music","sfx","ambience"],"description":"Declared audio role: 'vo' (narration), 'music' (bed that ducks under speech), 'sfx' (one-shot hit), 'ambience' (a bed that HOLDS under VO — never ducks)."}},"required":["url","filename","contentType"],"additionalProperties":false,"description":"POST /media/import body."},"MediaImportResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","const":"importing"}},"required":["id","status"],"additionalProperties":false,"description":"POST /media/import response."},"MediaListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MediaResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"MediaResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"source":{"type":"string","enum":["upload","generated","stock"]},"name":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"number"},"duration":{"type":["number","null"]},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"frameRate":{"type":["number","null"]},"progress":{"anyOf":[{"type":"object","properties":{"phase":{"type":"string"},"percent":{"type":["number","null"]}},"required":["phase","percent"],"additionalProperties":false},{"type":"null"}]},"analysis":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}]},"listUsd":{"description":"A2 money stamp — GENERATED media only: the generate meter's LIST price (USD) at the success terminal. A plan allowance may zero the invoice line. Absent for uploads/imports, failures, x402 (on-chain receipts).","type":"number"},"thumbnailUrl":{"description":"Presigned GET URL for the item's thumbnail (an uploaded image is its own thumbnail), valid ~7 days — fetch it directly, no auth header. null when no thumbnail exists yet (still processing, stock imports, audio).","type":["string","null"]},"kind":{"type":["string","null"]},"tags":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"attribution":{"anyOf":[{"type":"object","properties":{"provider":{"type":"string","enum":["pexels","pixabay","freesound","klipy"]},"externalId":{"type":["string","null"]},"assetUrl":{"type":["string","null"]},"license":{"type":["string","null"]}},"required":["provider","externalId","assetUrl","license"],"additionalProperties":false},{"type":"null"}]},"processingStatus":{"anyOf":[{"$ref":"#/components/schemas/MediaProcessingStatus"},{"type":"null"}]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","status","source","name","mimeType","fileSize","duration","width","height","frameRate","progress","analysis","thumbnailUrl","kind","tags","attribution","processingStatus","createdAt","updatedAt"],"additionalProperties":false,"description":"Media item response per §Media."},"MediaProcessingStatus":{"type":"object","properties":{"phase":{"type":"string","enum":["idle","pending_import","pending_upload","uploading","extracting","loading_model","transcribing","proxy","embedding","analyzing","indexing","generating","rendering","processing","complete","error","cancelled"]},"percent":{"type":["number","null"]},"message":{"type":["string","null"]},"error":{"type":["string","null"]}},"required":["phase"],"additionalProperties":false,"description":"Processing status stored on mediaItems rows."},"MediaUploadRequest":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":500},"contentType":{"type":"string","enum":["video/mp4","video/quicktime","video/x-matroska","video/webm","audio/mpeg","audio/wav","audio/x-wav","audio/mp4","audio/aac","image/png","image/jpeg","image/webp","image/gif","image/svg+xml","application/json","font/ttf","font/otf","font/woff","font/woff2"]},"size":{"type":"integer","exclusiveMinimum":0,"maximum":10737418240},"projectId":{"type":"string","minLength":1}},"required":["filename","contentType","size"],"additionalProperties":false,"description":"POST /media upload initiation body."},"MuxJobResponse":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string"},"muxedItems":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},{"type":"null"}]},"error":{"type":["string","null"]},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]}},"required":["jobId","status"],"additionalProperties":false,"description":"Mux job response."},"PreviewClipRequest":{"type":"object","properties":{"fromSec":{"type":"number","minimum":0,"description":"Window start, seconds into the composition."},"toSec":{"type":"number","exclusiveMinimum":0,"description":"Window end (exclusive), seconds."},"compositionId":{"description":"Target a specific composition; defaults to the project's active composition.","type":"string","minLength":1}},"required":["fromSec","toSec"],"additionalProperties":false,"description":"POST /projects/:id/preview-clip body."},"PreviewFrameRequest":{"type":"object","properties":{"composition":{"description":"The composition to render. Absent ⇒ the project's ACTIVE composition — what create_render will encode. The response's `previewed.source` names what was rendered."},"compositionId":{"description":"Preview a SPECIFIC persisted composition of this project (create_render parity). Absent ⇒ the active one. A stale/foreign id is a 404 — never a silent fall-through.","type":"string"},"session_id":{"description":"Compose-session id: render that session's SCRATCH composition (what the session has been editing) instead of the active row. Ignored when `composition` is passed.","type":"string"},"timestamps":{"minItems":1,"maxItems":18,"type":"array","items":{"type":"number"},"description":"Composition seconds to capture, 18 per request. The batch renders as ONE unit of work — one warm container, one source decode, N seeks — and that unit has a fixed time budget, so a larger batch is refused here rather than accepted and timed out minutes later. For a denser sweep, split it across calls; identical beats are served from the still cache, so overlapping batches are cheap."},"imageFormat":{"description":"Still format. Default jpeg — these pixels go to a vision model, where jpeg is equivalent and png costs multiples in bytes to store and move. Pass png only when you need full fidelity.","type":"string","enum":["png","jpeg"]},"scale":{"description":"Render scale 0.1–1. Default 0.5, which is what this schema has always recommended for vision-bound looks. Pass 1 when judging fine detail — it costs ~4x the vision tokens.","type":"number","minimum":0.1,"maximum":1},"jpegQuality":{"description":"JPEG quality (jpeg only). Default 70 — the quality the eval panel grades at.","type":"integer","minimum":1,"maximum":100}},"required":["timestamps"],"additionalProperties":false,"example":{"timestamps":[1.5,4],"imageFormat":"jpeg"}},"ProfileResponse":{"type":"object","properties":{"brandKits":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"audio":{"type":"object","properties":{"sfxIntensity":{"type":"string","enum":["off","light","standard","dense"]},"musicEnabled":{"type":"boolean"},"musicMood":{"type":"string","maxLength":300},"sonicLogo":{"description":"A brand sound signature bound to the intro/outro bookend. `ref` = a palette reference; bound only when the kit carries the matching bumper (intro/outro), else a non-blocking advisory.","type":"object","properties":{"ref":{"type":"string","minLength":1},"placement":{"type":"string","enum":["intro","outro","both"]},"offsetMs":{"type":"integer","minimum":0,"maximum":10000}},"required":["ref","placement"],"additionalProperties":false},"uiSoundSet":{"description":"Per-family SFX overrides (the brand's own tick/pop/…). Highest-priority tier over the org palette + pack default in the compose SFX draw.","type":"object","properties":{"tick":{"type":"string","minLength":1},"pop":{"type":"string","minLength":1},"impact":{"type":"string","minLength":1},"confirm":{"type":"string","minLength":1},"error":{"type":"string","minLength":1},"whoosh":{"type":"string","minLength":1},"riser":{"type":"string","minLength":1}},"additionalProperties":false},"bedStyle":{"description":"Preferred music bed (`bedId`) or a style hint (`genre` / `bpmRange`). Surfaced for driving agents; compose does not auto-select a pack bed.","type":"object","properties":{"bedId":{"type":"string","minLength":1},"genre":{"type":"string","maxLength":120},"bpmRange":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"],"additionalProperties":false}},"additionalProperties":false},"ambiencePreference":{"description":"Preferred ambience bed (`{ref}`) or explicit null (opt-out). Surfaced for driving agents; compose has no ambience auto-placement.","anyOf":[{"type":"object","properties":{"ref":{"type":"string","minLength":1}},"required":["ref"],"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false}},"required":["id","name"],"additionalProperties":false},"description":"The org's brand kits (bind one to a project via update_project). `audio` carries the brand sound kit when set."},"critics":{"type":"array","items":{"$ref":"#/components/schemas/CriticSummary"},"description":"Registered critics — run in the Director's gates AND score_composition."},"references":{"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string"},"name":{"type":"string"},"thumbnailUrl":{"description":"Presigned reference thumbnail (~1 week).","type":"string"}},"required":["mediaId"],"additionalProperties":false},"description":"The union of critic reference media — the org's visual standard, with provenance."},"recentDecisions":{"type":"array","items":{"type":"object","properties":{"checkpointId":{"type":"string"},"projectId":{"type":"string"},"kind":{"type":"string","enum":["gate","score"]},"stage":{"type":"string","enum":["content","layout","motion"]},"decision":{"type":"string"},"decidedAt":{"type":"number"}},"required":["checkpointId","projectId","kind","decision","decidedAt"],"additionalProperties":false},"description":"The last recorded checkpoint decisions — the raw taste log phase 2 will distill."}},"required":["brandKits","critics","references","recentDecisions"],"additionalProperties":false,"description":"The org's legible taste: brand + critics + references + decision log."},"ProjectCompositionSummary":{"type":"object","properties":{"hasComposition":{"type":"boolean"},"sceneCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"duration":{"type":["number","null"]},"updatedAt":{"type":["string","null"]}},"required":["hasComposition","sceneCount","duration","updatedAt"],"additionalProperties":false,"description":"Summary of a project's stored composition."},"ProjectContextResponse":{"type":"object","properties":{"composition":{"anyOf":[{"$ref":"#/components/schemas/Composition"},{"type":"null"}],"description":"The project's ACTIVE composition wire shape — identical to GET /v1/projects/{id}/composition. NULL when the project has no composition yet (a freshly created project): mint one with new_composition, or let the first apply_composition create it."},"format":{"anyOf":[{"type":"object","properties":{"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1","4:5"]},"fps":{"anyOf":[{"type":"number","const":24},{"type":"number","const":25},{"type":"number","const":30},{"type":"number","const":60}]},"resolution":{"type":"string","enum":["hd","fhd","4k"]},"platform":{"type":"string"}},"required":["aspectRatio"],"additionalProperties":false},{"type":"null"}],"description":"The composition's format, hoisted — the pixel frame every card/graphic must be authored against. Null whenever `composition` is null."},"media":{"type":"array","items":{"$ref":"#/components/schemas/ProjectContextMedia"},"description":"The org's media library (most recent first, capped) — the pool this project can draw clips from."},"transcript":{"anyOf":[{"$ref":"#/components/schemas/ProjectContextTranscript"},{"type":"null"}],"description":"The FIRST transcribed media item's word-timed transcript, flattened — the spine a VO-driven film cuts to. `status:\"ready\"` carries the words; `status:\"unavailable\"` means the transcript exists but its body could not be fetched (retry); null means nothing in `media` is transcribed. For any OTHER transcribed item (see each entry's `hasTranscript`), read GET /v1/media/{id}/transcript."},"brandKit":{"anyOf":[{"$ref":"#/components/schemas/BrandKitResponse"},{"type":"null"}],"description":"The kit BOUND to this project (`projects.brandKitId` is the brand SSOT — bind one via update_project). Null when the project has no kit bound; enumerate the org's kits with GET /v1/brand-kits."},"markers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1},"startTime":{"type":"number","minimum":0},"endTime":{"type":"number","minimum":0},"kind":{"type":"string","minLength":1},"name":{"type":"string"},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","startTime","kind"],"additionalProperties":false},"description":"The composition's markers — hoisted alongside `format`. Empty when the composition carries none AND when there is no composition yet."}},"required":["composition","format","media","transcript","brandKit","markers"],"additionalProperties":false,"description":"One-call agent context for a project: composition + format + media pool + the lead transcript + the bound brand kit + markers. Replaces get_composition + get_media_context + get_profile at the start of an authoring session. A 404 means the project doesn't exist for your org — never that it is empty."},"ProjectContextMedia":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":["string","null"]},"durationSec":{"description":"Seconds. Uses the media duration when known; audio without one falls back to its transcript's measured duration (same rule as get_media_context).","type":["number","null"]},"hasTranscript":{"type":"boolean","description":"A cached transcript EXISTS for this item. The bodies are never inlined here — fetch one with GET /v1/media/{id}/transcript (or get_media_context for faces + grids too)."}},"required":["id","name","kind","durationSec","hasTranscript"],"additionalProperties":false,"description":"One media item as the project context lists it: identity + duration + whether a transcript exists."},"ProjectContextTranscript":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","const":"ready"},"mediaId":{"type":"string"},"words":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"start":{"type":"number","description":"Word onset (SECONDS from source start)."},"end":{"type":"number","description":"Word end (SECONDS from source start)."}},"required":["text","start","end"],"additionalProperties":false}}},"required":["status","mediaId","words"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"unavailable"},"mediaId":{"type":"string"}},"required":["status","mediaId"],"additionalProperties":false}],"type":"object"},"ProjectCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string"},"format":{"$ref":"#/components/schemas/FormatSpec"},"brandKitId":{"type":"string","minLength":1},"width":{"deprecated":true,"type":"number","exclusiveMinimum":0},"height":{"deprecated":true,"type":"number","exclusiveMinimum":0}},"required":["name"],"additionalProperties":false,"description":"POST /projects body."},"ProjectLastRender":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string"},"outputUrl":{"type":["string","null"]},"outputExpiresAt":{"type":["string","null"]}},"required":["id","status","createdAt","outputUrl","outputExpiresAt"],"additionalProperties":false},{"type":"null"}],"description":"Most recent render for a project, if any."},"ProjectListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProjectResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"ProjectResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"format":{"anyOf":[{"$ref":"#/components/schemas/FormatSpec"},{"type":"null"}]},"brandKitId":{"type":["string","null"]},"activeCompositionId":{"type":["string","null"]},"composition":{"$ref":"#/components/schemas/ProjectCompositionSummary"},"lastRender":{"$ref":"#/components/schemas/ProjectLastRender"},"webUrl":{"description":"A browser URL that opens THIS project, or null when CueFrame exposes no web view for a project. Null today: the console serves account surfaces (keys, usage, billing) and has no per-project page, so there is no link to give. Do NOT synthesise one — a guessed console path 404s. Show the user rendered output (create_render → outputUrl) or a preview still instead. This field becoming non-null is the signal that a real project view exists.","type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","name","description","format","brandKitId","activeCompositionId","composition","lastRender","webUrl","createdAt"],"additionalProperties":false,"description":"Project response per §Projects."},"ProjectPatchRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string"},"format":{"$ref":"#/components/schemas/FormatSpec"},"brandKitId":{"type":"string","minLength":1}},"additionalProperties":false,"description":"PATCH /projects/:id body."},"RenderCreateRequest":{"type":"object","properties":{"clipSuggestionId":{"type":"string","minLength":1},"compositionId":{"type":"string","minLength":1,"description":"Target a specific composition in the project; defaults to the project's active composition."},"format":{"$ref":"#/components/schemas/FormatSpec"},"priority":{"type":"string","enum":["interactive","standard","background"]},"intent":{"type":"string","enum":["preview","final"]},"brandKitId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}]}},"additionalProperties":false,"description":"POST /projects/:id/renders body."},"RenderFontsResponse":{"type":"object","properties":{"manifestVersion":{"type":"string","description":"Identifies this exact face table. Derived from the table's own content, so it moves when and only when the admitted set moves. Record it beside a composition to state which face table a font choice was validated against."},"families":{"type":"array","items":{"type":"object","properties":{"family":{"type":"string","description":"The family name authoring accepts VERBATIM — card, caption and scene text alike."},"weights":{"type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"],"additionalProperties":false},"description":"The weights a shipped file declares. A static face has min === max; a variable face gives its declared wght axis range. Any weight inside a range renders; anything outside every range is REFUSED, never synthesised."},"styles":{"type":"array","items":{"type":"string","enum":["normal","italic"]},"description":"The styles bytes exist for in this family. Request italic only when this list includes 'italic'; the renderer refuses synthetic slant."},"captionDefaults":{"type":"object","properties":{"base":{"type":"number"},"emphasis":{"type":"number"}},"required":["base","emphasis"],"additionalProperties":false,"description":"The weights a caption is drawn at when the style names none."},"origin":{"type":"string","enum":["bundled","aliased"],"description":"'bundled' = bytes ship in the render bundle. 'aliased' = a metric-compatible binary stands in for the named family."}},"required":["family","weights","styles","captionDefaults","origin"],"additionalProperties":false}}},"required":["manifestVersion","families"],"additionalProperties":false,"description":"GET /fonts response — the renderer's admitted font set. Derived from the same table the font gate refuses by, so any family/weight/style here passes validation by construction. Covers the BUNDLED set only: a brand kit's sealed faces are per-org and per-render."},"RenderListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RenderResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"RenderResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","pending","rendering","complete","error","cancelled"]},"progress":{"$ref":"#/components/schemas/RenderProgress"},"outputUrl":{"type":["string","null"]},"outputExpiresAt":{"type":["string","null"]},"error":{"description":"Human-readable failure message. Pair with `errorCode` for a stable, machine-readable code an agent runner can branch on.","type":["string","null"]},"errorCode":{"description":"Stable, machine-readable error code (e.g. `render_pipeline_unavailable`, `render_route_missing`, `render_pipeline_failed`). Null when status is not `error` or unavailable for an older render.","type":["string","null"]},"errorDetails":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Structured failure context — `{ targetUrl?, upstreamStatus?, upstreamCode?, attemptedAt? }`. Surfaced so agent runners can distinguish operator-config issues from upstream-down vs route-missing without parsing `error`."},"category":{"anyOf":[{"type":"string","enum":["authoring","transient","internal"]},{"type":"null"}],"description":"Failure taxonomy when status is `error`; null otherwise. `authoring` = deterministic defect in YOUR composition/request — fix it, retrying is futile; `transient` = temporary pipeline/infra failure — safe to retry_render; `internal` = unexpected server fault — retry once then escalate. Mirrors the render.failed webhook's `category`."},"retryable":{"description":"Whether re-attempting the SAME render can succeed (status `error`); null otherwise. true → call retry_render. false → deterministic (category authoring/internal); fix the composition first — retry_render alone reproduces it. Mirrors the render.failed webhook's `retryable`.","type":["boolean","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp of the render's most recent progress update. Compute staleness = now − updatedAt to distinguish a wedged render from a slow one and decide whether to wait, cancel, or retry."},"listUsd":{"description":"A2 money stamp: the metered event's LIST price (USD), stamped at the success terminal (exports for deliverable renders, compose_capture for A8 previews). A plan allowance may zero the actual invoice line — this is the list price, never a Stripe charge. Absent while running, on failure, and for x402 orgs (on-chain receipts). Mirrors the get_usage ledger.","type":"number"},"warnings":{"description":"Non-fatal advisories surfaced at render-CREATE (omitted when none, and on GET — create-time only).","type":"array","items":{"type":"string"}}},"required":["id","status","outputUrl","outputExpiresAt","error","errorCode","errorDetails","category","retryable","createdAt","updatedAt"],"additionalProperties":false,"description":"Render job response per §Renders."},"RenderProgress":{"type":"object","properties":{"phase":{"type":"string","enum":["queued","validating","presigning","collecting-artifacts","resolving","detecting","baking-matte","translating","spawning","encoding","uploading"]},"percent":{"type":"number"},"scenesCompleted":{"type":"integer","minimum":0,"maximum":9007199254740991},"scenesTotal":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["phase","percent"],"additionalProperties":false,"description":"Non-terminal render progress; phase is one of the worker's emitted stages."},"RenderRefreshUrlResponse":{"type":"object","properties":{"outputUrl":{"type":"string"},"outputExpiresAt":{"type":"string"}},"required":["outputUrl","outputExpiresAt"],"additionalProperties":false,"description":"POST /refresh-url response."},"ResourceCandidate":{"type":"object","properties":{"candidateId":{"type":"string"},"provider":{"type":"string","enum":["pexels","pixabay","freesound","klipy"]},"kind":{"type":"string","enum":["video","photo","sfx","gif"]},"thumbnail":{"type":"string"},"previewUrl":{"type":"string"},"downloadUrl":{"type":"string"},"duration":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"},"author":{"type":"string"},"authorUrl":{"type":"string"},"assetUrl":{"type":"string"},"license":{"type":"string"}},"required":["candidateId","provider","kind","thumbnail","previewUrl","author"],"additionalProperties":false,"description":"A stock resource search candidate."},"ResourceImportRequest":{"type":"object","properties":{"kind":{"type":"string","enum":["sfx-pack","music-pack"]},"id":{"type":"string","minLength":1},"projectId":{"type":"string","minLength":1},"candidateId":{"type":"string","minLength":1}},"additionalProperties":false,"description":"POST /resources/import body — stock candidate lane { projectId, candidateId } OR curated pack lane { kind:\"sfx-pack\"|\"music-pack\", id }.","example":{"projectId":"abcdefghij1234567890abcdef123456","candidateId":"cand_01J8Z3K9Q2X4Y5W6V7T8R9S0P1"}},"ResourceImportResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["importing","ready"]}},"required":["id","status"],"additionalProperties":false,"description":"POST /resources/import response."},"ResourceSearchRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200},"queries":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"kind":{"type":"string","enum":["video","photo","sfx","gif"]},"provider":{"type":"string","enum":["pexels","pixabay","freesound","klipy"]},"limit":{"type":"integer","exclusiveMinimum":0,"maximum":50},"minWidth":{"description":"Video-only minimum selected-rendition width in pixels; smaller results are excluded.","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"minHeight":{"description":"Video-only minimum selected-rendition height in pixels; smaller results are excluded.","type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"durationSec":{"type":"object","properties":{"min":{"type":"number","minimum":0},"max":{"type":"number","exclusiveMinimum":0}},"additionalProperties":false,"description":"sfx-only clip-length bound in seconds → Freesound native filter."}},"additionalProperties":false,"description":"POST /resources/search body — one `query`, or a batch of `queries[]`."},"ResourceSearchResponse":{"type":"object","properties":{"provider":{"type":"string","enum":["pexels","pixabay","freesound","klipy"]},"kind":{"type":"string","enum":["video","photo","sfx","gif"]},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/ResourceCandidate"}},"results":{"type":"array","items":{"$ref":"#/components/schemas/ResourceSearchResult"}}},"additionalProperties":false,"description":"POST /resources/search response — `candidates` for one query, `results[]` for a batch."},"ResourceSearchResult":{"type":"object","properties":{"query":{"type":"string"},"provider":{"type":"string","enum":["pexels","pixabay","freesound","klipy"]},"kind":{"type":"string","enum":["video","photo","sfx","gif"]},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/ResourceCandidate"}},"error":{"type":"string"}},"required":["query","candidates"],"additionalProperties":false,"description":"One query's candidates within a batch search."},"ReviewDecisionResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"stage":{"type":"string","enum":["content","layout","motion"]},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"composeJobId":{"type":"string"}},"required":["ok"],"additionalProperties":false,"description":"Decision recorded; the run resumes (the SAME rail as POST /checkpoints/{id}/resume)."},"ReviewPacketResponse":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"composeJobId":{"type":"string"},"briefId":{"type":"string"},"kind":{"type":"string","enum":["gate","score"]},"stage":{"$ref":"#/components/schemas/CheckpointStage"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["awaiting","approved","revised","abandoned","expired","superseded"]},"artifact":{"description":"The stage artifact under review: the locked ComposePlan at content; the composition wire shape at layout/motion; the judged composition snapshot on kind:'score'."},"stillUrls":{"description":"Presigned storyboard/eval stills — the packet's visual evidence (may be GC'd by the retention sweep after the job goes terminal; the decision record is immortal).","type":"array","items":{"type":"string"}},"criticVerdicts":{"description":"Per-criterion scores + critique from the design loop / judge, incl. lock_violation entries."},"quote":{"$ref":"#/components/schemas/CheckpointQuote"},"revisionCycle":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Revise cycles this gate has consumed. The brief quote states the included count (revisionCyclesIncluded); beyond it, resume(revise) is refused with a typed error."},"decision":{"description":"The recorded decision {decision, comments?, globalNote?, decidedAt} once resolved."},"reviewMode":{"description":"How this packet is decided (from the Brief's gates). 'hosted' = the review PAGE captures the decision; absent/'agent' = the decision flows back through the driving agent.","type":"string","enum":["agent","hosted"]},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"versionStack":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"stage":{"type":"string","enum":["content","layout","motion"]},"status":{"type":"string"},"decision":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","version","status","createdAt"],"additionalProperties":false},"description":"The run's v1→vN gate history — per-version status + decision summaries."}},"required":["id","projectId","kind","version","status","artifact","revisionCycle","createdAt","updatedAt","versionStack"],"additionalProperties":false},"ScoreCompositionRequest":{"type":"object","properties":{"composition":{"description":"The composition to judge. Absent ⇒ the project's ACTIVE composition."},"compositionId":{"description":"Judge a SPECIFIC persisted composition of this project (create_render parity). Absent ⇒ the active one. A stale/foreign id is a 404 — never a silent fall-through.","type":"string"},"session_id":{"description":"Compose-session id: judge that session's SCRATCH composition (what the session has been editing) instead of the active row. Ignored when `composition` is passed.","type":"string"},"editorialIntent":{"type":"string"},"brandContext":{"type":"string"}},"additionalProperties":false,"example":{"editorialIntent":"punchy, founder-led"}},"SelectorCandidatesResponse":{"type":"object","properties":{"projectId":{"type":"string"},"groupId":{"type":"string"},"selectorVersion":{"type":"string"},"signalVersions":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"moments":{"type":"array","items":{"$ref":"#/components/schemas/SelectorMomentGroup"}},"recommendation":{"type":"object","properties":{"cutSchedule":{"type":"array","items":{"$ref":"#/components/schemas/SelectorCutSpan"}},"audioBed":{"type":"array","items":{"$ref":"#/components/schemas/SelectorAudioSpan"},"description":"Best-audio bed (instance #3): the clearest mic per span."},"suppressedSwitches":{"type":"array","items":{"type":"object","properties":{"atSec":{"type":"number"},"wouldHaveBeenCandidateId":{"type":"string"},"byScore":{"type":"number"},"blockedBy":{"type":"string"},"releaseAtSec":{"type":["number","null"]}},"required":["atSec","wouldHaveBeenCandidateId","byScore","blockedBy","releaseAtSec"],"additionalProperties":false},"description":"Switches the stabilizer suppressed (the anti-ping-pong audit)."}},"required":["cutSchedule","audioBed","suppressedSwitches"],"additionalProperties":false},"divergesFromComposition":{"type":"boolean"}},"required":["projectId","groupId","selectorVersion","signalVersions","moments","recommendation"],"additionalProperties":false,"description":"Selector (switch) candidates + recommendation for a synced-angle group. Every candidate carries score + contributions + reasons so the agent reweights from evidence; the recommendation is the lowered cut schedule + best-audio bed."},"SelectorMomentGroup":{"type":"object","properties":{"startSec":{"type":"number","description":"Span start (output seconds)."},"endSec":{"type":"number","description":"Span end (output seconds)."},"chosen":{"type":"string","description":"The recommended candidateId, or \"__hold__\" (abstain)."},"pacingNote":{"description":"Which mechanism produced the pick (argmax / hysteresis / override / hold …).","type":["string","null"]},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/SelectorScoredCandidate"}}},"required":["startSec","endSec","chosen","candidates"],"additionalProperties":false},"SelectorScoredCandidate":{"type":"object","properties":{"candidateId":{"type":"string","description":"Stable angle/source id. An unknown id is rejected, never remapped."},"role":{"description":"Agent-declared semantic tag (e.g. \"wide\", \"webcam\").","type":["string","null"]},"score":{"type":"number","description":"The weighted prominence score (Σ weights·signal)."},"contributions":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number"},"description":"signalKey → weighted contribution (the agent reweights from this)."},"reasons":{"type":"array","items":{"type":"string"}}},"required":["candidateId","score","contributions","reasons"],"additionalProperties":false},"SelectorCutSpan":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"},"candidateId":{"type":"string"},"sourceInSec":{"type":"number","description":"Chosen source window start (declared-offset resolved)."},"sourceOutSec":{"type":"number"},"reasons":{"type":"array","items":{"type":"string"}}},"required":["startSec","endSec","candidateId","sourceInSec","sourceOutSec","reasons"],"additionalProperties":false},"SelectorAudioSpan":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"},"candidateId":{"type":"string","description":"The chosen audio source (the clearest mic) for this span → programAudioSourceId."},"reasons":{"type":"array","items":{"type":"string"}}},"required":["startSec","endSec","candidateId","reasons"],"additionalProperties":false},"SelectorPreviewRequest":{"type":"object","properties":{"groupId":{"type":"string","minLength":1},"weights":{"description":"Sparse prominence weights (the taste knob, non-negative). Default = DOMINANCE_WEIGHTS.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"number"}},"minHoldSec":{"type":"number","exclusiveMinimum":0},"enterSec":{"type":"number","minimum":0},"switchMargin":{"type":"number","minimum":0},"cooldownSec":{"type":"number","minimum":0},"maxHoldSec":{"type":"number","exclusiveMinimum":0},"lockSourceId":{"description":"Pin a camera/angle for the whole timeline.","type":"string"},"overrides":{"type":"array","items":{"type":"object","properties":{"startSec":{"type":"number"},"endSec":{"type":"number"},"candidateId":{"type":"string"}},"required":["startSec","endSec","candidateId"],"additionalProperties":false}}},"required":["groupId"],"additionalProperties":false},"SessionCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"files":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"object","properties":{"mediaId":{"type":"string","minLength":1},"role":{"type":"string","minLength":1,"maxLength":50}},"required":["mediaId","role"],"additionalProperties":false}}},"required":["name","files"],"additionalProperties":false,"description":"POST /sessions body."},"SessionFileEntry":{"type":"object","properties":{"mediaId":{"type":"string"},"role":{"type":"string"},"status":{"type":["string","null"]}},"required":["mediaId","role","status"],"additionalProperties":false,"description":"One file member of a session, with optional role + status."},"SessionListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SessionSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"SessionSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"fileCount":{"type":"integer","minimum":0,"maximum":9007199254740991},"muxStatus":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","name","fileCount","muxStatus","createdAt"],"additionalProperties":false,"description":"Session list summary (per list endpoint)."},"SessionResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"files":{"type":"array","items":{"$ref":"#/components/schemas/SessionFileEntry"}},"mux":{"type":"object","properties":{"status":{"type":["string","null"]},"jobId":{"type":["string","null"]},"muxedItems":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},{"type":"null"}]},"error":{"type":["string","null"]},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]}},"required":["status","jobId","muxedItems","error","startedAt","completedAt"],"additionalProperties":false},"createdAt":{"type":"string"}},"required":["id","name","files","mux","createdAt"],"additionalProperties":false,"description":"Session response per §Sessions."},"SkillListResponse":{"type":"object","properties":{"skills":{"type":"array","items":{"$ref":"#/components/schemas/SkillSummary"}}},"required":["skills"],"additionalProperties":false,"description":"GET /skills response — the available agent skills."},"SkillSummary":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"}},"required":["name","title","description"],"additionalProperties":false,"description":"A CueFrame agent skill (metadata)."},"SubjectDetectionTriggerResponse":{"type":"object","properties":{"factId":{"type":"string","description":"Opaque identifier for the derived fact."},"status":{"type":"string","enum":["pending","ready","failed"],"description":"State of the fact right now. `ready` with `alreadyExisted` means the detection was already computed and is available immediately."},"quotedUsd":{"type":"number","description":"The server's price for this detection, in USD, quoted from the source duration. Zero is charged when `alreadyExisted` is true."},"alreadyExisted":{"type":"boolean","description":"True when this exact detection was already pending or ready. Nothing was dispatched and nothing will be charged — the same fact is served twice for one price."}},"required":["factId","status","quotedUsd","alreadyExisted"],"additionalProperties":false,"description":"POST /media/:id/detect-subjects response — the claimed perception fact."},"Suggestion":{"type":"object","properties":{"id":{"type":"string"},"briefId":{"type":["string","null"]},"rank":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"trim":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"}},"required":["start","end"],"additionalProperties":false},"score":{"type":"number"},"title":{"type":"string"},"reason":{"type":"string"},"topic":{"type":"string"},"hook":{"type":"string"},"platforms":{"type":"array","items":{"type":"string"}},"format":{"type":"string"},"caption":{"type":"string"},"hashtags":{"type":"array","items":{"type":"string"}},"textOverlays":{"type":"array","items":{"type":"string"}},"editingNotes":{"type":"string"},"motionStyle":{"type":"object","properties":{"textAnimation":{"type":"string"},"transitions":{"type":"string"},"colorMood":{"type":"string"},"captionStyle":{"type":"string"}},"required":["textAnimation","transitions","colorMood","captionStyle"],"additionalProperties":false},"visualTreatment":{"type":"array","items":{"type":"object","properties":{"time":{"type":["number","string"]},"visual":{"type":"string"}},"required":["time","visual"],"additionalProperties":false}},"brollSuggestions":{"type":"array","items":{"type":"object","properties":{"moment":{"type":"string"},"searchTerms":{"type":"array","items":{"type":"string"}},"rationale":{"type":"string"}},"required":["moment","searchTerms","rationale"],"additionalProperties":false}},"thumbnailConcept":{"type":"string"}},"required":["id","briefId","rank","trim","score","title","reason","topic","hook","platforms","format","caption","hashtags","textOverlays","editingNotes","motionStyle","visualTreatment","brollSuggestions","thumbnailConcept"],"additionalProperties":false,"description":"Single ranked clip suggestion."},"SuggestionsEnvelope":{"type":"object","properties":{"status":{"type":"string","enum":["idle","generating","completed","failed"]},"createdAt":{"type":["string","null"]},"analyzedAt":{"type":["string","null"]},"jobId":{"type":["string","null"]},"topics":{"type":"array","items":{"type":"string"}},"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/Suggestion"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["status","createdAt","analyzedAt","jobId","topics","suggestions","pagination"],"additionalProperties":false,"description":"GET /media/:id/suggestions envelope."},"SuggestionsTriggerResponse":{"type":"object","properties":{"status":{"type":"string","enum":["queued","running","complete","failed"]},"alreadyRunning":{"type":"boolean"}},"required":["status"],"additionalProperties":false,"description":"POST /media/:id/suggestions response."},"TemplateApplyPendingResponse":{"type":"object","properties":{"templateId":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pendingMediaIds":{"type":"array","items":{"type":"string"}}},"required":["templateId","version","pendingMediaIds"],"additionalProperties":false},"TemplateApplyRequest":{"type":"object","properties":{"componentExecutionVersions":{"minItems":1,"maxItems":1,"type":"array","items":{"type":"number","const":3}},"expectedBrandIdentity":{"type":"string","pattern":"^[a-f0-9]{64}$"},"projectId":{"type":"string","minLength":1},"values":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"media":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/TemplateMediaValue"}},"preset":{"type":"string","minLength":1},"brandKitId":{"type":"string","minLength":1}},"required":["projectId","values","media"],"additionalProperties":false,"examples":[{"projectId":"observed-project","values":{},"media":{}}]},"TemplateMediaValue":{"anyOf":[{"type":"object","properties":{"mediaId":{"type":"string","minLength":1}},"required":["mediaId"],"additionalProperties":false},{"type":"object","properties":{"url":{"type":"string","format":"starts_with","pattern":"^https:\\/\\/.*"},"mimeType":{"type":"string","minLength":1}},"required":["url"],"additionalProperties":false},{"type":"object","properties":{"sample":{"type":"boolean","const":true}},"required":["sample"],"additionalProperties":false}]},"TemplateApplyResponse":{"type":"object","properties":{"projectId":{"type":"string"},"compositionId":{"type":"string"},"versionId":{"type":"string"},"etag":{"type":"string"},"templateId":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"components":{"type":"array","items":{"type":"object","properties":{"documentKey":{"type":"string"},"componentId":{"type":"string"},"sourceVersionId":{"type":"string"},"created":{"type":"boolean"}},"required":["documentKey","componentId","sourceVersionId","created"],"additionalProperties":false}}},"required":["projectId","compositionId","versionId","etag","templateId","version","components"],"additionalProperties":false},"TemplateInstantiateRequest":{"type":"object","properties":{"projectName":{"type":"string","minLength":1,"maxLength":200},"values":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"media":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/TemplateMediaValue"}},"preset":{"type":"string","minLength":1},"brandKitId":{"type":"string","minLength":1}},"required":["projectName","values","media"],"additionalProperties":false},"TemplateInstantiationJobResponse":{"type":"object","properties":{"jobId":{"type":"string"},"projectId":{"type":["string","null"]},"status":{"type":"string","enum":["preparing","ready","failed","cancelled"]},"stage":{"type":"string","enum":["resolving","downloading","verifying","importing","processing","attaching","applying","preflighting","ready"]},"templateRef":{"type":"string"},"documentSha256":{"type":["string","null"]},"errorCode":{"type":"string"},"errorMessage":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["jobId","projectId","status","stage","templateRef","documentSha256","createdAt","updatedAt"],"additionalProperties":false},"TemplateListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateSummary"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"TemplateSummary":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"documentSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"fromCatalog":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","slug","name","version","documentSha256","fromCatalog","createdAt","updatedAt"],"additionalProperties":false},"TemplatePublishRequest":{"anyOf":[{"$ref":"#/components/schemas/TemplatePublishDocumentRequest"},{"$ref":"#/components/schemas/TemplatePublishSlugRequest"}]},"TemplatePublishDocumentRequest":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/TemplateDocument"},"dryRun":{"description":"When true, store nothing: answer 200 with the kernel's verdict on the document as `TemplateValidateResponse`. Without `values`, `media` or `preset` the document itself is checked (every preset binds against the parameters' samples and placeholder values for required parameters that have no default). With any of them, only the caller's inputs are bound, `{ mediaId }` values against this org's real media rows.","type":"boolean"},"values":{"description":"Dry run only (400 without `dryRun: true`): parameter values to bind, by parameter name.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"media":{"description":"Dry run only (400 without `dryRun: true`): media values to bind, by media parameter name.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/TemplateDryRunMediaValue"}},"preset":{"description":"Dry run only (400 without `dryRun: true`): the preset whose values the bind starts from.","type":"string","minLength":1}},"required":["document"],"additionalProperties":false},"TemplateDocument":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A CueFrame template document (kernel TemplateDocument): v: 1, slug, name, composition with {{name}} references, parameters, components by value, an optional brandKit, presets, rubric, gallery and provenance."},"TemplateDryRunMediaValue":{"anyOf":[{"type":"object","properties":{"mediaId":{"type":"string","minLength":1}},"required":["mediaId"],"additionalProperties":false},{"type":"object","properties":{"sample":{"type":"boolean","const":true}},"required":["sample"],"additionalProperties":false}],"description":"A media value a dry run can resolve without importing anything: `{ mediaId }` (one of this org's media rows) or `{ sample: true }` (the parameter's pinned sample)."},"TemplatePublishSlugRequest":{"type":"object","properties":{"slug":{"type":"string","maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}},"required":["slug"],"additionalProperties":false},"TemplateRenderCreateRequest":{"type":"object","properties":{"values":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"media":{"default":{},"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"$ref":"#/components/schemas/TemplateMediaValue"}},"preset":{"type":"string","minLength":1},"brandKitId":{"type":"string","minLength":1},"posterAt":{"description":"Seconds into the render for the poster still; default 1.","type":"number","minimum":0}},"required":["values","media"],"additionalProperties":false},"TemplateRenderResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["preparing","rendering","complete","failed","cancelled","revoked"]},"templateId":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"preset":{"type":"string"},"brandKitId":{"type":"string"},"shareUrl":{"type":["string","null"]},"posterUrl":{"type":["string","null"]},"renderId":{"type":["string","null"]},"errorCode":{"type":"string"},"errorMessage":{"type":"string"},"expiresAt":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","status","templateId","version","shareUrl","posterUrl","renderId","createdAt","updatedAt"],"additionalProperties":false},"TemplateResponse":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"documentSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"fromCatalog":{"type":"boolean"},"document":{"$ref":"#/components/schemas/TemplateDocument"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","slug","name","version","documentSha256","fromCatalog","document","createdAt","updatedAt"],"additionalProperties":false},"TemplateValidateResponse":{"type":"object","properties":{"ok":{"type":"boolean","description":"True when the kernel found no problem."},"slug":{"description":"The document's slug, or null when the document did not carry one.","type":["string","null"]},"problems":{"type":"array","items":{"$ref":"#/components/schemas/TemplateProblem"},"description":"Every problem found, in the order the kernel's checks run; empty when `ok`."}},"required":["ok","slug","problems"],"additionalProperties":false},"TemplateProblem":{"type":"object","properties":{"code":{"type":"string","description":"The problem's code: template_parse, template_parameter_undeclared, template_reference_misplaced, template_media_site, template_matte_stale, template_sample_missing, template_media_required, template_preset_unknown, template_values_invalid, template_media_kind_mismatch or payload_too_large."},"param":{"description":"The parameter the problem names, when it names one.","type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},"TimelineAnalysisRequest":{"type":"object","properties":{"words":{"minItems":1,"maxItems":12000,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":1000},"timelineStart":{"type":"number","minimum":0},"timelineEnd":{"type":"number","minimum":0},"clipId":{"type":"string","minLength":1,"maxLength":256},"poolItemId":{"type":"string","minLength":1,"maxLength":256},"sourceStart":{"type":"number","minimum":0},"sourceEnd":{"type":"number","minimum":0},"speakerId":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}]}},"required":["text","timelineStart","timelineEnd","clipId","poolItemId","sourceStart","sourceEnd","speakerId"],"additionalProperties":false}}},"required":["words"],"additionalProperties":false,"description":"A bounded merged timeline transcript for CueFrame edit analysis. The server selects the model; clients cannot provide a provider, API key, or model override."},"TimelineAnalysisResponse":{"type":"object","properties":{"fillers":{"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}},"silenceGaps":{"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}},"emphasis":{"type":"array","items":{"type":"integer","minimum":0,"maximum":9007199254740991}}},"required":["fillers","silenceGaps","emphasis"],"additionalProperties":false,"description":"CueFrame-model analysis of timeline word indices. Every returned index refers to the request's words array."},"TraceScoresRequest":{"type":"object","properties":{"scores":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"value":{"type":"number","minimum":0,"maximum":1},"comment":{"type":"string","maxLength":500}},"required":["name","value"],"additionalProperties":false}}},"required":["scores"],"additionalProperties":false,"description":"POST /traces/:traceId/scores body."},"TraceScoresResponse":{"type":"object","properties":{"accepted":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["accepted"],"additionalProperties":false,"description":"POST /traces/:traceId/scores response."},"TranscriptAnalyzeRequest":{"type":"object","properties":{"task":{"type":"string","enum":["summary","chapters","highlights"],"description":"What to ask of the transcript. `summary` — prose: the argument plus the concrete takeaways as bullets. `chapters` — one line per subject change, `[h:mm:ss] Title — description`. `highlights` — up to 8 standalone moments, strongest first, one line each as `[h:mm:ss]-[h:mm:ss] Title — why it lands` plus the line that carries it. Every timestamp is ABSOLUTE seconds from the start of the media, including when you pass a `window`, and every one is verified against the transcript before you see it — but they are LINE-START markers about 15s apart, so treat a span as APPROXIMATE (up to 15s early) and refine it against the word timings from GET /v1/media/{id}/context before you cut."},"window":{"description":"Analyse only this slice of the transcript. Omit to analyse all of it. Words are windowed exactly as captions.fromTranscript windows them (a word straddling an edge is clamped, a word wholly outside is dropped). Use this when a long recording is rejected with `transcript_too_long`, and to chapter a single segment of a podcast without paying for the whole thing.","type":"object","properties":{"startSec":{"type":"number","minimum":0,"description":"Window start, SECONDS from the start of the media."},"endSec":{"type":"number","minimum":0,"description":"Window end, SECONDS from the start of the media."}},"required":["startSec","endSec"],"additionalProperties":false}},"required":["task"],"additionalProperties":false,"description":"One editorial question about a media item's transcript."},"TranscriptAnalyzeResponse":{"type":"object","properties":{"task":{"type":"string","enum":["summary","chapters","highlights"],"description":"Echo of the requested task — so a batched caller can pair answers to asks."},"result":{"type":"string","description":"The answer, as text. `summary` is prose; `chapters` and `highlights` are one record per LINE in the shape documented on the request's `task` field — split on newlines to parse them. Timestamps are absolute seconds from the start of the media and every one is CHECKED against the transcript before the response is returned (a fabricated timestamp fails the call rather than shipping), but they are line-start markers about 15s apart — a boundary can sit up to 15s BEFORE the moment you want. Use them to locate, not to cut: refine against the word timings in GET /v1/media/{id}/context."}},"required":["task","result"],"additionalProperties":false,"description":"The analysis of one media item's transcript. Metered: this is a real LLM call, billed on measured token spend, so it is not a read to poll."},"UploadTokenRequest":{"type":"object","properties":{"projectId":{"description":"Optional project to scope the token to; omitted = org library.","type":"string"}},"additionalProperties":false},"UploadTokenResponse":{"type":"object","properties":{"token":{"type":"string"},"expiresAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Expiry, ms since epoch (~30 min TTL)."}},"required":["token","expiresAt"],"additionalProperties":false,"description":"POST /uploads/token response: a short-lived token for the signed upload lane (the upload-signing worker's `uppy-auth-token` header). The org is derived from the session server-side and stamped into the token."},"UsageEventResponse":{"type":"object","properties":{"featureId":{"type":"string","description":"The metered plan feature (exports, compose, compose_verify, …)."},"value":{"description":"Metered amount, in the feature's own unit (exports = render-minutes, storage = GB). Absent for a discrete single use, AND deliberately absent on the cost-plus lines (compose, generate, ai_tokens, compose_verify) whose internal metered unit is not a quantity — read `listUsd` for what those events cost you.","type":"number"},"projectId":{"type":"string"},"jobId":{"description":"The job that produced the meter: a render/compose/preview job id, a media id (transcription, generate), or a clip-suggestion run id (jobKind `suggestions` — see `mediaItemId` for the media it analyzed).","type":"string"},"jobKind":{"description":"render | compose | consult_* | verify | preview | generate | suggestions | session_uptime | …","type":"string"},"mediaItemId":{"description":"The media item the job ran over, when it ran over one (suggestions, transcription). Resolve it with GET /v1/media/{id}.","type":"string"},"listUsd":{"description":"LIST price of this metered event, USD. Honest naming: the invoice may zero it inside a plan allowance — this is the event's list price, not a Stripe line item.","type":"number"},"createdAt":{"type":"number","description":"Epoch-ms when the meter landed."}},"required":["featureId","createdAt"],"additionalProperties":false},"UsageListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UsageEventResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"WebhookCreateRequest":{"type":"object","properties":{"url":{"type":"string","minLength":1,"format":"uri","example":"https://hooks.example.com/cueframe"},"events":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"settleMs":{"type":"integer","minimum":0,"maximum":60000}},"required":["url","events"],"additionalProperties":false,"description":"POST /webhooks body."},"WebhookEvent":{"type":"string","enum":["media.transcribed","media.completed","suggest.completed","session.mux.complete","session.mux.failed","render.completed","compose.completed","checkpoint.ready","project.updated","composition.updated","webhook.test"]},"WebhookCreateResponse":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"settleMs":{"type":"integer","minimum":0,"maximum":9007199254740991},"enabled":{"type":"boolean"},"status":{"type":"string","enum":["active","pending"],"description":"active = ownership verified + receiving events; pending = challenge not echoed, inactive."},"secret":{"type":"string","description":"Standard Webhooks signing secret, format `whsec_<base64>`. Returned ONCE at create; rotate = delete + recreate. Every delivery carries `webhook-id`, `webhook-timestamp` (unix seconds), and `webhook-signature: v1,<base64>` (HMAC-SHA256 over `{id}.{timestamp}.{rawBody}`). Verify with any Standard-Webhooks library (`standardwebhooks` / `svix`): `new Webhook(secret).verify(rawBody, headers)`."},"verification":{"description":"Present ONLY when ownership verification did not complete (status:\"pending\"). CueFrame POSTs a signed `webhook.verify` challenge whose `data.token` your endpoint must echo in a 2xx to activate; `reason` is one of token_not_echoed | non_2xx_<code> | unreachable | ssrf_blocked. A pending webhook receives no events — fix the receiver and POST /webhooks/:id/verify (no delete/recreate needed). See GET /webhooks/events for the full contract.","type":"object","properties":{"status":{"type":"string","const":"pending"},"reason":{"type":"string"}},"required":["status","reason"],"additionalProperties":false}},"required":["id","url","events","settleMs","enabled","status","secret"],"additionalProperties":false,"description":"POST /webhooks response (secret present exactly once)."},"WebhookEventCatalogResponse":{"type":"object","properties":{"delivery":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The shared HTTP envelope + headers + retry semantics."},"signing":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Standard Webhooks signing: secret format, signed content, how to verify."},"ownershipVerification":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"The synchronous echo-the-token activation handshake + recovery."},"events":{"type":"array","items":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/WebhookEvent"},"when":{"type":"string"},"data":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["event","when","data"],"additionalProperties":{}},"description":"Every subscribable event with its exact delivery `data` fields."},"sample":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"A fully-worked example delivery (headers + body)."}},"required":["delivery","signing","ownershipVerification","events","sample"],"additionalProperties":false,"description":"The webhook delivery/signing/verification contract, as data. Read this before building a receiver."},"WebhookListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookResponse"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"additionalProperties":false},"WebhookResponse":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"settleMs":{"type":"integer","minimum":0,"maximum":9007199254740991},"enabled":{"type":"boolean"},"verificationStatus":{"type":"string","enum":["pending","verified"],"description":"pending = callback URL has not echoed the ownership challenge (receives no events); verified = ownership proven."},"createdAt":{"type":"string"},"lastDeliveredAt":{"type":["string","null"]},"lastFailedAt":{"type":["string","null"]},"consecutiveFailures":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","url","events","settleMs","enabled","verificationStatus","createdAt","lastDeliveredAt","lastFailedAt","consecutiveFailures"],"additionalProperties":false,"description":"Webhook endpoint record (secret omitted after create)."},"WebhookPatchRequest":{"type":"object","properties":{"url":{"type":"string","minLength":1,"format":"uri","example":"https://hooks.example.com/cueframe"},"events":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"}},"settleMs":{"type":"integer","minimum":0,"maximum":60000},"enabled":{"type":"boolean"}},"additionalProperties":false,"description":"PATCH /webhooks/:id body."},"WebhookTestResponse":{"type":"object","properties":{"deliveryId":{"type":"string"},"status":{"type":"string","const":"queued"}},"required":["deliveryId","status"],"additionalProperties":false,"description":"POST /webhooks/:id/test response."},"WebhookVerifyResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["active","pending"],"description":"active = ownership verified + receiving events; pending = challenge not echoed."},"verification":{"description":"Present only when the re-challenge did not verify; `reason` names why (see WebhookCreateResponse.verification).","type":"object","properties":{"status":{"type":"string","const":"pending"},"reason":{"type":"string"}},"required":["status","reason"],"additionalProperties":false}},"required":["id","status"],"additionalProperties":false,"description":"POST /webhooks/:id/verify response."},"WhoamiResponse":{"type":"object","properties":{"orgId":{"type":"string"},"permissions":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"array","items":{"type":"string"}}},"keyId":{"type":"string"},"keyName":{"type":"string"}},"required":["orgId","permissions","keyId","keyName"],"additionalProperties":false,"description":"Whoami response."},"WorkspaceCreateRequest":{"type":"object","properties":{"videoUrl":{"type":"string","maxLength":2048,"format":"uri"},"format":{"$ref":"#/components/schemas/FormatSpec"}},"required":["videoUrl"],"additionalProperties":false,"example":{"videoUrl":"https://example.com/talk.mp4"}},"X402PaymentRequired":{"type":"object","title":"X402PaymentRequired","description":"x402 v2 PaymentRequired challenge — the body of a 402 on a priced operation.","properties":{"x402Version":{"type":"integer","const":2},"accepts":{"type":"array","description":"Accepted payment requirements. Read `accepts[0]` for scheme (`exact` for a fixed price, `upto` for a measured one), network (CAIP-2), asset, amount and payTo.","items":{"type":"object"}},"error":{"type":"string","description":"Human-readable reason."}},"required":["x402Version","accepts"]}}},"paths":{"/v1/health":{"get":{"operationId":"health","tags":["health"],"summary":"Shallow + deep health check","description":"Shallow (default) returns 200 with a minimal liveness payload for load balancers. Append `?deep=1` to exercise component bindings (rate-limiter). Unauthenticated.","parameters":[{"name":"deep","in":"query","required":false,"description":"Pass `1` to run the deep dependency checks instead of the shallow liveness probe.","schema":{"type":"string","const":"1"}}],"security":[],"responses":{"200":{"description":"Healthy (or `?deep=1` checks pass).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/review/{id}":{"get":{"operationId":"getReviewPacket","tags":["checkpoints"],"summary":"Read a hosted review packet (token-authenticated page data)","description":"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.","security":[],"responses":{"200":{"description":"The review packet + version stack.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewPacketResponse"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}]}},"/v1/review/{id}/decision":{"post":{"operationId":"recordReviewDecision","tags":["checkpoints"],"summary":"Record a hosted review decision (the same resume rail)","description":"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).","security":[],"responses":{"200":{"description":"Decision recorded; the run resumes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewDecisionResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}]}},"/v1/skills":{"get":{"operationId":"listSkills","tags":["skills"],"summary":"List available CueFrame agent skills","description":"Returns the agent skills CueFrame publishes (e.g. `cueframe-cli`). Metadata only — fetch the markdown body from GET /skills/{name}. Unauthenticated, like /openapi.json.","security":[],"responses":{"200":{"description":"The available skills.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillListResponse"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/skills/{name}":{"get":{"operationId":"getSkill","tags":["skills"],"summary":"Get a skill's SKILL.md (markdown)","description":"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.","security":[],"responses":{"200":{"description":"The skill's SKILL.md markdown.","content":{"text/markdown":{"schema":{"type":"string"}}}},"404":{"description":"No skill with that name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"name","required":true}]}},"/v1/whoami":{"get":{"operationId":"whoami","tags":["health"],"summary":"Return the caller identity + permissions","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"responses":{"200":{"description":"Authenticated caller identity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoamiResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/me":{"get":{"operationId":"getAccount","tags":["account"],"summary":"Return the caller's account: identity, plan, entitlements, cost ceilings","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"responses":{"200":{"description":"The caller's account, plan, entitlements, and cost ceilings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects":{"get":{"operationId":"listProjects","tags":["projects"],"summary":"List projects","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated projects.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"createProject","tags":["projects"],"summary":"Create a project","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreateRequest"}}}},"responses":{"201":{"description":"Project created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}":{"get":{"operationId":"getProject","tags":["projects"],"summary":"Get a project by id","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"patch":{"operationId":"patchProject","tags":["projects"],"summary":"Update a project","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectPatchRequest"}}}},"responses":{"200":{"description":"Project updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"deleteProject","tags":["projects"],"summary":"Delete a project","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/composition":{"get":{"operationId":"getComposition","tags":["compositions"],"summary":"Get a project's composition","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"componentExecutionVersions","in":"query","required":false,"description":"Explicit accepted saved component execution protocol. Absent readers accept only the historical protocol.","schema":{"type":"string","const":"3"}},{"name":"includeDependencies","in":"query","required":false,"description":"Return the immutable composition identity, project revision and shared v1 dependency expectations alongside the composition.","schema":{"type":"string","enum":["true","false"]}},{"name":"compositionId","in":"query","required":false,"description":"Read a SPECIFIC composition instead of the project's active one. Omit it and the active composition is returned. Pairs with `composition_id` on the apply op: an edit you can make to a second composition is one you can read back.","schema":{"type":"string"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"The composition wire shape, or its observed dependency envelope when requested.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionReadResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"put":{"operationId":"putComposition","tags":["compositions"],"summary":"Replace a project's composition","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionReplaceRequest"}}}},"responses":{"200":{"description":"Composition saved; new ETag in header."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compositions":{"post":{"operationId":"newComposition","tags":["compositions"],"summary":"Create a new composition (video) in a project","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionCreateRequest"}}}},"responses":{"201":{"description":"Composition created."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listCompositions","tags":["compositions"],"summary":"List a project's compositions","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Compositions in the project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/composition/ops":{"post":{"operationId":"applyCompositionOp","tags":["compositions"],"summary":"Apply one operation to a project's composition","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionOp"}}}},"responses":{"200":{"description":"Op applied; new ETag in header."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/composition/apply":{"post":{"operationId":"applyComposition","tags":["compositions"],"summary":"Apply a batch of operations to a project's composition (or dry-run validate)","description":"Atomically applies an array of CompositionOps. All ops succeed or none do (transactional). Pass `if_match` for optimistic-concurrency control (409 stale_etag on mismatch). 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionApplyRequest"}}}},"responses":{"200":{"description":"Batch applied (`{ contract, applied, etag, diffs }`, ETag header set), OR dry-run validation (`{ contract, valid, errors }`) when `dry_run: true`. Either shape may additionally carry `warnings: string[]` (omitted when there are none). `contract` is the kernel version that judged the batch; a change between calls means the validator moved, not your composition."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/composition/from-suggestion":{"post":{"operationId":"composeFromSuggestion","tags":["clips"],"summary":"Build and persist a composition from a clip suggestion","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositionFromSuggestionRequest"}}}},"responses":{"200":{"description":"Composition saved; new ETag in header."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compositions/derive":{"post":{"operationId":"deriveComposition","tags":["compositions"],"summary":"Derive a reframed sibling composition for a new aspect (multi-format)","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeriveCompositionRequest"}}}},"responses":{"200":{"description":"Sibling created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeriveCompositionResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/composition/validate":{"post":{"operationId":"validateComposition","tags":["compositions"],"summary":"Validate a composition body without saving it (dry-run)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Composition"}}}},"responses":{"200":{"description":"Validation verdict (ALWAYS 200 for a JSON body — both wire-shape and deep-invariant failures). `valid:false` lists authoring errors (envelopes) to fix before save/render; `valid:true` means the composition passes every pure save-time guard.","content":{"application/json":{"schema":{"type":"object","properties":{"contract":{"type":"string","description":"The contract this verdict was computed against (the kernel version the deployment runs). If it differs between two calls, the validator changed, not your composition."},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"stage":{"type":"string"},"category":{"type":"string"},"retryable":{"type":"boolean"},"message":{"type":"string"},"fix":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["code","stage","category","retryable","message"],"additionalProperties":false}},"advisories":{"type":"array","items":{"type":"object","properties":{"rule":{"type":"string"},"criterion":{"type":"string"},"clipId":{"type":"string"},"detail":{"type":"string"},"fix":{"type":"string"}},"required":["rule","criterion","detail","fix"],"additionalProperties":false},"description":"Deterministic, render-free QUALITY floors (the SAME named defects the Director's in-loop verify and score_composition surface: static-hold, caption-spine, sfx-density, sfx-speech-collision, bed-coverage, audio-role). NON-blocking — they never flip `valid` (an editorially-weak composition still renders); fix them for quality, not to save. Empty when the composition is clean or the wire shape failed (they need a parsed composition)."},"warnings":{"description":"Non-blocking render-fidelity warnings detected before enqueue, including unavailable font families.","type":"array","items":{"type":"string"}},"quote":{"type":"object","properties":{"thisStepUsd":{"type":"number"},"jobSpendSoFarUsd":{"type":"number"},"estimatedJourneyTotalUsd":{"type":"number"}},"required":["thisStepUsd","jobSpendSoFarUsd","estimatedJourneyTotalUsd"],"additionalProperties":false,"description":"The A2 money triple for the commodity lane: validate is free; estimatedJourneyTotalUsd is the render price to finish from a valid composition — relay it BEFORE create_render."}},"required":["contract","valid","errors","advisories","quote"],"additionalProperties":false}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compositions/{compositionId}":{"delete":{"operationId":"deleteComposition","tags":["compositions"],"summary":"Delete a composition","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"compositionId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/search":{"get":{"operationId":"searchLibrary","tags":["media"],"summary":"Semantic search over the org's own footage","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"q","in":"query","required":true,"description":"What the moment should look like, in plain language. Describe the IMAGE, not the words spoken.","schema":{"type":"string","minLength":1}},{"name":"limit","in":"query","required":false,"description":"Maximum moments to return. Default 10, maximum 25.","schema":{"type":"integer","minimum":1,"maximum":25,"default":10}}],"responses":{"200":{"description":"Matching moments, best first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LibrarySearchResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/uploads/token":{"post":{"operationId":"createUploadToken","tags":["media"],"summary":"Mint a short-lived token for the signed upload lane","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadTokenRequest"}}}},"responses":{"201":{"description":"Upload token minted (~30 min TTL).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadTokenResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media":{"post":{"operationId":"createMediaUpload","tags":["media"],"summary":"Initiate a direct upload (presigned PUT URL)","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaUploadRequest"}}}},"responses":{"201":{"description":"Presigned PUT URL issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaDirectUploadResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listMedia","tags":["media"],"summary":"List media items","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"kind","in":"query","required":false,"description":"Filter to one media kind.","schema":{"type":"string","enum":["video","audio","image","gif","asset","source","stock"]}},{"name":"source","in":"query","required":false,"description":"Filter by how the item entered the library.","schema":{"type":"string","enum":["upload","generated","import-url","stock"]}},{"name":"tag","in":"query","required":false,"description":"Filter to items carrying this EXACT tag (not a prefix or substring match).","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated media items.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/finalize":{"post":{"operationId":"finalizeMedia","tags":["media"],"summary":"Finalize a direct upload (trigger processing after the bytes are PUT)","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaFinalizeRequest"}}}},"responses":{"200":{"description":"Ingest triggered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaFinalizeResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/generate":{"post":{"operationId":"generateMedia","tags":["media"],"summary":"Generate media with AI (video, image, or Manim animation)","description":"Generate a new media item from a text prompt: text-to-video, text-to-image, image-to-video, or a programmatic Manim animation (generator 'auto' picks the best one for the prompt). 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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"generate","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaGenerateRequest"}}}},"responses":{"201":{"description":"Generation enqueued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaGenerateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}}},"/v1/media/import":{"post":{"operationId":"importMedia","tags":["media"],"summary":"Import media from a URL (server-side fetch)","description":"Import media into the project from a public https URL — the server fetches and mirrors the bytes (SSRF-filtered), then processes it (transcode + transcribe). 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"import","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaImportRequest"}}}},"responses":{"201":{"description":"Import enqueued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaImportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}":{"delete":{"operationId":"deleteMedia","tags":["media"],"summary":"Delete a media item","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"getMedia","tags":["media"],"summary":"Get a media item by id","description":"Required permission: media:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"responses":{"200":{"description":"Media item.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/transcript":{"get":{"operationId":"getMediaTranscript","tags":["media"],"summary":"Get a media transcript (paginated)","description":"Required permission: media:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"after","in":"query","description":"Zero-based utterance cursor returned as pagination.nextCursor.","schema":{"type":"integer","minimum":0}},{"name":"before","in":"query","description":"Zero-based utterance cursor for a backward page. Do not combine with after.","schema":{"type":"integer","minimum":0}},{"name":"limit","in":"query","description":"Utterances per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Transcript.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/context":{"get":{"operationId":"getMediaContext","tags":["media"],"summary":"Get authoring context for a media item (faces + transcript + beat/word grids)","description":"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. 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"responses":{"200":{"description":"Authoring context.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaContextResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/suggestions":{"get":{"operationId":"listMediaSuggestions","tags":["clips"],"summary":"List clip suggestions for a media item","description":"Required permission: media:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"platform","in":"query","required":false,"description":"Only suggestions cut for this delivery platform.","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"Only suggestions in this output format.","schema":{"type":"string"}},{"name":"topic","in":"query","required":false,"description":"Only suggestions matching this topic label.","schema":{"type":"string"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Clip suggestions envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionsEnvelope"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"suggestBriefs","tags":["clips"],"summary":"Trigger clip-suggestion analysis","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"suggestions","responses":{"202":{"description":"Analysis triggered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestionsTriggerResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"resetMediaSuggestions","tags":["clips"],"summary":"Reset clip suggestions for a media item","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"responses":{"200":{"description":"Suggestions deleted (count returned)."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/detect-subjects":{"post":{"operationId":"triggerSubjectDetection","tags":["media"],"summary":"Trigger standalone subject/face detection","description":"Required permission: media:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"detect","parameters":[{"name":"detector","in":"query","required":false,"description":"Which detector to run. Defaults to `face`; an unknown value is refused, never defaulted.","schema":{"type":"string","enum":["face","person"]}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"202":{"description":"Detection claimed. `alreadyExisted:true` means this exact detection was already pending or ready — nothing was dispatched and nothing will be charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectDetectionTriggerResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"100000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/matte":{"post":{"operationId":"triggerMatteBake","tags":["media"],"summary":"Buy a behind-subject matte for one source window","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatteBakeRequest"}}}},"responses":{"202":{"description":"Matte bake dispatched (`alreadyExisted:false`), or the matte already exists (`alreadyExisted:true`) — in which case nothing was dispatched and nothing will be charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatteBakeTriggerResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/facts":{"get":{"operationId":"listMediaFacts","tags":["media"],"summary":"List derived facts for a media item, with quotes for what is missing","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"kind","in":"query","required":false,"description":"Resolve one exact editor prerequisite. Requires startSec and endSec; the response includes the server-selected `exact` result.","schema":{"type":"string","enum":["subjectTrack","matte"]}},{"name":"startSec","in":"query","required":false,"description":"Source-in of the clip's trim, in seconds. Must be sent WITH endSec — one without the other is a 400, never a silent whole-source default.","schema":{"type":"number"}},{"name":"endSec","in":"query","required":false,"description":"Source-out of the clip's trim, in seconds. Must be sent WITH startSec.","schema":{"type":"number"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Facts + offers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaFactsResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"purchaseMediaFact","tags":["media"],"summary":"Buy a derived fact (subject track or behind-subject matte)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"detect","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaFactPurchaseRequest"}}}},"responses":{"202":{"description":"Fact claimed (dispatched, or already present).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaFactPurchaseResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"100000"},"protocols":[{"x402":{}}]}}},"/v1/media/{id}/transcript/analyze":{"post":{"operationId":"analyzeTranscript","tags":["media"],"summary":"Analyse a media item's transcript","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":{"amount":"50000"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptAnalyzeRequest"}}}},"responses":{"200":{"description":"The analysis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptAnalyzeResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}}},"/v1/timeline-analysis":{"post":{"operationId":"analyzeTimeline","tags":["media"],"summary":"Analyze a timeline transcript for edit decisions","description":"Returns filler, silence-gap, and emphasis word indices for an editor timeline. Analysis settings are selected server-side and cannot be overridden.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":{"amount":"50000"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineAnalysisRequest"}}}},"responses":{"200":{"description":"Timeline analysis completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimelineAnalysisResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/context":{"get":{"operationId":"getProjectContext","tags":["projects"],"summary":"One-call agent context: composition + media + transcript + brand","description":"Everything an authoring agent needs to open a project, in ONE read: the active composition (with its format and markers hoisted), the org'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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"],"media":["read"]},"responses":{"200":{"description":"Aggregated context.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectContextResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/resources/search":{"post":{"operationId":"searchResources","tags":["resources"],"summary":"Search stock media (Pexels / Pixabay / Freesound / Klipy)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceSearchRequest"}}}},"responses":{"200":{"description":"Ranked stock candidates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceSearchResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/resources/import":{"post":{"operationId":"importResource","tags":["resources"],"summary":"Import a stock candidate or a curated SFX-pack sound","description":"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:<soundId> }: 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["write"]},"x-x402":"import","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceImportRequest"}}}},"responses":{"201":{"description":"Import reserved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceImportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/fonts/search":{"post":{"operationId":"searchFonts","tags":["fonts"],"summary":"Search web font families by name/style","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FontSearchRequest"}}}},"responses":{"200":{"description":"Matching web font families.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FontSearchResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/fonts":{"get":{"operationId":"listRenderFonts","tags":["fonts"],"summary":"List the font faces the renderer can actually draw","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"responses":{"200":{"description":"The renderer's admitted font faces.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderFontsResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders":{"post":{"operationId":"createRender","tags":["renders"],"summary":"Create a render job","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"x-x402":"render","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderCreateRequest"}}}},"responses":{"201":{"description":"Render queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"412":{"description":"Precondition failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"428":{"description":"Precondition required — If-Match missing on a mutated resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listProjectRenders","tags":["renders"],"summary":"List renders for a project","description":"Required permission: renders:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Comma-separated render statuses to include (e.g. `error,cancelled`). Omit for every status.","schema":{"type":"string"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Paginated render jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/preview-clip":{"post":{"operationId":"previewClip","tags":["renders"],"summary":"Render a scoped motion preview of the composition","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"x-x402":{"amount":"50000","deliverable":true,"maxTimeoutSeconds":900},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewClipRequest"}}}},"responses":{"201":{"description":"Preview render queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"50000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders/{renderId}":{"get":{"operationId":"getRender","tags":["renders"],"summary":"Get a render job","description":"Required permission: renders:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["read"]},"responses":{"200":{"description":"Render job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders/{renderId}/cancel":{"post":{"operationId":"cancelRender","tags":["renders"],"summary":"Cancel a render","description":"Required permission: renders:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"200":{"description":"Cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders/{renderId}/retry":{"post":{"operationId":"retryRender","tags":["renders"],"summary":"Re-render against an existing renderJob's snapshot","description":"Required permission: renders:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"201":{"description":"Retry queued — returns a NEW renderJob with status=queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders/{renderId}/refresh-url":{"post":{"operationId":"refreshRenderUrl","tags":["renders"],"summary":"Refresh a render's output URL","description":"Required permission: renders:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"200":{"description":"New output URL issued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenderRefreshUrlResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/renders/{renderId}/stream":{"get":{"operationId":"streamRender","tags":["renders"],"summary":"Stream render status (SSE)","description":"Server-Sent Events stream emitting `progress`, `complete`, and `error` frames until the render reaches a terminal state. Required scope: renders:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["read"]},"responses":{"200":{"description":"SSE stream (text/event-stream).","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — scope insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Render not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/exports/fcpxml":{"post":{"operationId":"createFcpxmlExport","tags":["exports"],"summary":"Create a Final Cut Pro export","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportCreateRequest"}}}},"responses":{"202":{"description":"Export queued. Poll GET /projects/:id/exports/:exportId for progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/exports/premiere":{"post":{"operationId":"createPremiereExport","tags":["exports"],"summary":"Create a Premiere Pro export","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportCreateRequest"}}}},"responses":{"202":{"description":"Export queued. Poll GET /projects/:id/exports/:exportId for progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/exports/{exportId}":{"get":{"operationId":"getExport","tags":["exports"],"summary":"Get an export job","description":"Required permission: renders:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["read"]},"responses":{"200":{"description":"Export job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"exportId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/exports/{exportId}/cancel":{"post":{"operationId":"cancelExport","tags":["exports"],"summary":"Cancel an in-flight export","description":"Required permission: renders:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"200":{"description":"Cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"exportId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/brand-kits":{"get":{"operationId":"listBrandKits","tags":["brand-kits"],"summary":"List brand kits (read-only)","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated brand kits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"createBrandKit","tags":["brand-kits"],"summary":"Create (or upsert) a brand kit","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitCreateRequest"}}}},"responses":{"201":{"description":"Brand kit created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/brand-kits/extract":{"post":{"operationId":"extractBrandKit","tags":["brand-kits"],"summary":"Extract brand tokens from a website URL","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractBrandKitRequest"}}}},"responses":{"202":{"description":"Extraction job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobEnqueueResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/brand-kits/{id}":{"get":{"operationId":"getBrandKit","tags":["brand-kits"],"summary":"Get a brand kit by id","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"The brand kit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/brand-kits/{id}/exemplars":{"post":{"operationId":"getBrandKitExemplars","tags":["brand-kits"],"summary":"Presign a brand kit's inspiration exemplar frames","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitExemplarsRequest"}}}},"responses":{"200":{"description":"Presigned exemplar frames.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandKitExemplarsResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/brand-kits/exemplar-uploads":{"post":{"operationId":"createExemplarUploads","tags":["brand-kits"],"summary":"Reserve presigned PUT slots for inspiration exemplar frames","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExemplarUploadsRequest"}}}},"responses":{"201":{"description":"Presigned PUT slots reserved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExemplarUploadsResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates":{"post":{"operationId":"publishTemplate","tags":["templates"],"summary":"Publish a template document, or import a public catalog slug","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplatePublishRequest"}}}},"responses":{"200":{"description":"Dry run: the kernel's verdict on the document or the given inputs; nothing was stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateValidateResponse"}}}},"201":{"description":"The stored template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listTemplates","tags":["templates"],"summary":"List this org's templates","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated template summaries, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}":{"get":{"operationId":"getTemplate","tags":["templates"],"summary":"Read a template document","description":"By org template id or public slug. A public slug this org never used is read from the catalog and stored nowhere.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"The template with its document.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"deleteTemplate","tags":["templates"],"summary":"Delete a template","description":"Existing renders keep their snapshots and share links; new renders and applies of this id answer 404.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","responses":{"204":{"description":"Deleted."},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/instantiate":{"post":{"operationId":"instantiateTemplate","tags":["templates"],"summary":"Start a new project from a pinned template","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInstantiateRequest"}}}},"responses":{"202":{"description":"A durable preparation job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInstantiationJobResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/template-jobs/{jobId}":{"get":{"operationId":"getTemplateJob","tags":["templates"],"summary":"Read template preparation status","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Current preparation status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInstantiationJobResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/template-jobs/{jobId}/retry":{"post":{"operationId":"retryTemplateJob","tags":["templates"],"summary":"Retry a failed template preparation","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","responses":{"202":{"description":"Preparation resumed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInstantiationJobResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/template-jobs/{jobId}/cancel":{"post":{"operationId":"cancelTemplateJob","tags":["templates"],"summary":"Cancel template preparation","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"200":{"description":"Preparation cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateInstantiationJobResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/apply":{"post":{"operationId":"applyTemplate","tags":["templates"],"summary":"Apply a template to a project","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateApplyRequest"}}}},"responses":{"200":{"description":"The bound composition was saved onto the project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateApplyResponse"}}}},"202":{"description":"Media is still importing; apply again once every id is complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateApplyPendingResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/renders":{"post":{"operationId":"createTemplateRender","tags":["templates"],"summary":"Render a template to an MP4 with a share link","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"x-x402":"render","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateRenderCreateRequest"}}}},"responses":{"201":{"description":"The render, preparing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateRenderResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"500000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/renders/{renderId}":{"get":{"operationId":"getTemplateRender","tags":["templates"],"summary":"Read a template render","description":"Required permission: renders:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["read"]},"responses":{"200":{"description":"The render.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateRenderResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/renders/{renderId}/cancel":{"post":{"operationId":"cancelTemplateRender","tags":["templates"],"summary":"Cancel a template render","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"200":{"description":"The render, cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateRenderResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/templates/{id}/renders/{renderId}/revoke":{"post":{"operationId":"revokeTemplateRender","tags":["templates"],"summary":"Revoke a template render's share link","description":"The share link and poster answer 404 from now on; the render's output is kept. A render still in flight is cancelled first.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"renders":["write"]},"responses":{"200":{"description":"The render, revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateRenderResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"renderId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/briefs":{"post":{"operationId":"createBrief","tags":["briefs"],"summary":"Create a brief (the persisted intent the Director composes from)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefCreateRequest"}}}},"responses":{"201":{"description":"Brief created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listBriefs","tags":["briefs"],"summary":"List briefs (optionally scoped to a project)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"projectId","in":"query","required":false,"description":"Scope to one project. Omit for every brief in the org.","schema":{"type":"string"}},{"name":"kind","in":"query","required":false,"description":"Which briefs to list. `authored` (default) = human-authored only; `clip` = the machine-minted clip briefs from suggest_briefs; `all` = both.","schema":{"type":"string","enum":["authored","clip","all"]}}],"responses":{"200":{"description":"Paginated briefs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/briefs/{id}":{"get":{"operationId":"getBrief","tags":["briefs"],"summary":"Get a brief by id","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"The brief (with its quote).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"patch":{"operationId":"updateBrief","tags":["briefs"],"summary":"Edit a brief","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefPatchRequest"}}}},"responses":{"200":{"description":"Updated brief.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BriefResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"deleteBrief","tags":["briefs"],"summary":"Delete a brief","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/checkpoints":{"get":{"operationId":"listCheckpoints","tags":["checkpoints"],"summary":"List checkpoints (scope to a compose job or project)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"composeJobId","in":"query","required":false,"description":"Scope to ONE compose run — its v1→vN gate history with per-version status and decisions.","schema":{"type":"string"}},{"name":"projectId","in":"query","required":false,"description":"Scope to everything reviewable in one project.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated checkpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/checkpoints/{id}":{"get":{"operationId":"getCheckpoint","tags":["checkpoints"],"summary":"Get a checkpoint packet","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"The checkpoint packet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/checkpoints/{id}/resume":{"post":{"operationId":"resumeCheckpoint","tags":["checkpoints"],"summary":"Answer a held checkpoint (approve / revise / abandon)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointResumeRequest"}}}},"responses":{"200":{"description":"Decision recorded; the run resumes.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointResumeResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/score-composition":{"post":{"operationId":"scoreComposition","tags":["evidence"],"summary":"Score a composition (the standalone sighted judge)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":{"amount":"100000","deliverable":true,"maxTimeoutSeconds":4200},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScoreCompositionRequest"}}}},"responses":{"202":{"description":"Score job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobEnqueueResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"100000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/preview-frame-jobs":{"post":{"operationId":"previewFrameJob","tags":["evidence"],"summary":"Queue still-frame evidence for a composition","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":{"amount":"20000","deliverable":true,"maxTimeoutSeconds":3600},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewFrameRequest"}}}},"responses":{"202":{"description":"Preview-frame job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobEnqueueResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/component-preview":{"post":{"operationId":"previewComponent","tags":["evidence"],"summary":"Render one component preview","description":"Queue a preview of ONE org-installed component. It returns the SAME content-addressed VP9-alpha motion clip the production render composites. Returns a jobId — wait_job(kind='preview') for the artifact. Compile/runtime failures land on the job terminal with the sanitized author-fixable message.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":{"amount":"20000","deliverable":true,"maxTimeoutSeconds":600},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentPreviewRequest"}}}},"responses":{"202":{"description":"Preview job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobEnqueueResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/components":{"get":{"operationId":"listCatalog","tags":["components"],"summary":"List component catalog (defaults + installed)","description":"Discover the built-in primitive catalog (87 primitives + 7 scenes) plus your installed components. 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"projection","in":"query","required":false,"schema":{"type":"string","enum":["component-library"]}},{"name":"origin","in":"query","required":false,"description":"With component-library projection, builtin selects immutable builtin cards; library selects the authenticated org's exact serving datastore.","schema":{"type":"string","enum":["builtin","library"]}},{"name":"libraryKind","in":"query","required":false,"schema":{"type":"string","enum":["definition","preset","recipe"]}},{"name":"category","in":"query","required":false,"description":"Filter to one category bucket (text|effects|transitions|layouts|backgrounds|ui-blocks|scenes).","schema":{"type":"string","enum":["text","effects","transitions","layouts","backgrounds","ui-blocks","scenes"]}},{"name":"kind","in":"query","required":false,"description":"Filter by render kind (component|transition|scene).","schema":{"type":"string","enum":["component","transition","scene"]}},{"name":"tier","in":"query","required":false,"description":"Filter by curation tier (recommended|standard|niche).","schema":{"type":"string","enum":["recommended","standard","niche"]}},{"name":"useCase","in":"query","required":false,"description":"Filter to entries whose useCase includes this edit role (e.g. intro, title-over-footage, grade).","schema":{"type":"string","enum":["intro","outro","full-scene","title-over-footage","transition","background","grade","emphasis","explainer","social-cut"]}},{"name":"mood","in":"query","required":false,"description":"Filter to entries whose mood tags include this value (e.g. cinematic, minimal).","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Free-text match across id/name/description/intent/useWhen/tags/mood. Recommend-orders results.","schema":{"type":"string"}},{"name":"intent","in":"query","required":false,"description":"Alias of `q` framed as recommend-by-intent (e.g. intent=intro). Recommend-orders results.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size (1..100). Omit to return the whole filtered catalog in one page.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from a previous page's nextCursor (forward-only).","schema":{"type":"string"}}],"responses":{"200":{"description":"Component catalog (filtered + recommend-ordered).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"createComponent","tags":["components"],"summary":"Author (create) a component","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentCreateRequest"}}}},"responses":{"201":{"description":"Component created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/components/{id}":{"put":{"operationId":"updateComponent","tags":["components"],"summary":"Update an authored component","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentUpdateRequest"}}}},"responses":{"200":{"description":"Component updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentUpdateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"patch":{"operationId":"patchComponent","tags":["components"],"summary":"Patch an authored component","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentPatchRequest"}}}},"responses":{"200":{"description":"Component updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentUpdateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"getComponent","tags":["components"],"summary":"Get a component entry","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Component entry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/components/{id}/source":{"get":{"operationId":"getComponentSource","tags":["components"],"summary":"Get a component's source","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"parameters":[{"name":"builtinCollection","in":"query","required":false,"schema":{"type":"string","enum":["native","curated-definitions"]}},{"name":"sourceVersionId","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}},{"name":"supportedSourceVersions","in":"query","required":false,"description":"Comma-separated accepted source versions, e.g.2,3. Absence accepts the historical v2 protocol only.","schema":{"type":"string","pattern":"^(2|3)(,(2|3))?$"}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Component source (TSX) + ownership provenance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentSourceResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/sessions":{"get":{"operationId":"listSessions","tags":["sessions"],"summary":"List sessions","description":"Required permission: sessions:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated session summaries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"createSession","tags":["sessions"],"summary":"Create a session","description":"Required permission: sessions:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreateRequest"}}}},"responses":{"201":{"description":"Session created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/sessions/{id}":{"get":{"operationId":"getSession","tags":["sessions"],"summary":"Get a session","description":"Required permission: sessions:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["read"]},"responses":{"200":{"description":"Session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"deleteSession","tags":["sessions"],"summary":"Delete a session","description":"Required permission: sessions:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/sessions/{id}/mux-job":{"post":{"operationId":"triggerMuxJob","tags":["sessions"],"summary":"Trigger mux-audio-onto-video workflow","description":"Required permission: sessions:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["write"]},"x-x402":{"amount":"100000"},"responses":{"202":{"description":"Mux job enqueued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MuxJobResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"100000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"getMuxJob","tags":["sessions"],"summary":"Poll mux job status","description":"Required permission: sessions:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"sessions":["read"]},"responses":{"200":{"description":"Mux job status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MuxJobResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","tags":["webhooks"],"summary":"List webhook endpoints","description":"Required permission: webhooks:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated webhook endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"post":{"operationId":"createWebhook","tags":["webhooks"],"summary":"Register a webhook endpoint","description":"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,<base64>` (+ `x-cueframe-event`). The `secret` (`whsec_<base64>`) 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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["write"]},"x-x402":{"amount":"20000"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateRequest"}}}},"responses":{"201":{"description":"Webhook created (secret returned once).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/webhooks/events":{"get":{"operationId":"getWebhookEvents","tags":["webhooks"],"summary":"Get the webhook delivery contract","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["read"]},"responses":{"200":{"description":"The webhook delivery/signing/verification contract, as data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEventCatalogResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/webhooks/{id}":{"get":{"operationId":"getWebhook","tags":["webhooks"],"summary":"Get a webhook endpoint","description":"Required permission: webhooks:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["read"]},"responses":{"200":{"description":"Webhook endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"patch":{"operationId":"patchWebhook","tags":["webhooks"],"summary":"Update a webhook endpoint","description":"Required permission: webhooks:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookPatchRequest"}}}},"responses":{"200":{"description":"Webhook updated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"delete":{"operationId":"deleteWebhook","tags":["webhooks"],"summary":"Delete a webhook endpoint","description":"Required permission: webhooks:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/webhooks/{id}/test":{"post":{"operationId":"testWebhook","tags":["webhooks"],"summary":"Fire a webhook.test delivery","description":"Required permission: webhooks:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["write"]},"x-x402":{"amount":"20000"},"responses":{"202":{"description":"Test delivery queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/webhooks/{id}/verify":{"post":{"operationId":"verifyWebhook","tags":["webhooks"],"summary":"Re-run webhook ownership verification","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"webhooks":["write"]},"x-x402":{"amount":"20000"},"responses":{"200":{"description":"Verification result (active if the challenge was echoed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookVerifyResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/critics":{"post":{"operationId":"createCritic","tags":["critics"],"summary":"Register a compose critic","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriticCreateRequest"}}}},"responses":{"201":{"description":"Critic registered.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriticResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}},"get":{"operationId":"listCritics","tags":["critics"],"summary":"List registered critics (Profile family)","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Registered critics.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriticListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/critics/{criticId}":{"delete":{"operationId":"deleteCritic","tags":["critics"],"summary":"Delete a registered critic","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"criticId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/profile":{"get":{"operationId":"getProfile","tags":["account"],"summary":"Read the org's Profile — its legible taste","description":"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, and the recent checkpoint-decision log (what was approved/revised/abandoned, where). Read this before composing for an org you haven't worked with — it is the house style.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"The org profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/selector/candidates":{"get":{"operationId":"listSelectorCandidates","tags":["selector"],"summary":"List switch (multicam) candidates + recommendation for a synced-angle group","description":"Required permission: media:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"parameters":[{"name":"groupId","in":"query","required":true,"description":"The synced-angle group to score.","schema":{"type":"string","minLength":1}},{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Per-moment scored candidates + the recommended cut schedule + best-audio bed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectorCandidatesResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/selector/preview":{"post":{"operationId":"previewSelector","tags":["selector"],"summary":"Re-resolve a switch advisory under a hand-supplied policy (A/B taste; not persisted)","description":"Required permission: media:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"media":["read"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectorPreviewRequest"}}}},"responses":{"200":{"description":"The re-resolved advisory under the supplied policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectorCandidatesResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose":{"post":{"operationId":"compose","tags":["compose"],"summary":"Start an async Director compose workflow","description":"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`.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"compose","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeCreateRequest"}}}},"responses":{"202":{"description":"Compose job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeCreateResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose/jobs/{composeJobId}/stream":{"get":{"operationId":"streamCompose","tags":["compose"],"summary":"Stream compose progress (SSE)","description":"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","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"SSE stream (text/event-stream).","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — scope insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Compose job not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"composeJobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose/jobs/{composeJobId}/select":{"post":{"operationId":"selectComposeCandidate","tags":["compose"],"summary":"Promote a compose candidate to the active composition","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeSelectRequest"}}}},"responses":{"200":{"description":"Candidate selected; etag returned for adoption.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeSelectResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"Conflict — stale_etag / idempotency_conflict / suggestions_already_complete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"composeJobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose/jobs/{composeJobId}/cancel":{"post":{"operationId":"cancelCompose","tags":["compose"],"summary":"Cancel an in-flight compose job","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"200":{"description":"Cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeJobDetailResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"composeJobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose/jobs":{"get":{"operationId":"listComposeJobs","tags":["compose"],"summary":"List recent compose jobs for a project","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Job list (most recent first).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeJobListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose/jobs/{composeJobId}":{"get":{"operationId":"getComposeJob","tags":["compose"],"summary":"Fetch a compose job's full ensemble state","description":"Required permission: projects:read","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Job detail with candidates + per-criterion scores.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeJobDetailResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"composeJobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/consult":{"post":{"operationId":"consult","tags":["consult"],"summary":"Ask the multi-agent Director for editing advice (never writes)","description":"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.)","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"compose","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultRequest"}}}},"responses":{"202":{"description":"Consult job queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required — billing_required or x402 payment_*.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"dynamic","currency":"USDC"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose-session":{"post":{"operationId":"openComposeSession","tags":["compose-session"],"summary":"Open an isolated scratch composition","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"x-x402":"write","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComposeSessionOpenRequest"}}}},"responses":{"200":{"description":"Session opened.","content":{"application/json":{"schema":{"type":"object","properties":{"sessionId":{"type":"string"}},"required":["sessionId"],"additionalProperties":false}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose-session/{sessionId}/composition":{"get":{"operationId":"getComposeSessionComposition","tags":["compose-session"],"summary":"Read the session's scratch composition","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Scratch composition.","content":{"application/json":{"schema":{"type":"object","properties":{"composition":{}},"required":["composition"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"sessionId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose-session/{sessionId}":{"delete":{"operationId":"closeComposeSession","tags":["compose-session"],"summary":"Close a compose session","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"200":{"description":"Session closed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"sessionId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/projects/{id}/compose-session/{sessionId}/commit":{"post":{"operationId":"commitComposeSession","tags":["compose-session"],"summary":"Commit the session scratch onto the project's active composition","description":"Required permission: projects:write","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"200":{"description":"Promoted.","content":{"application/json":{"schema":{"type":"object","properties":{"etag":{"type":"string"}},"required":["etag"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true},{"schema":{"type":"string"},"in":"path","name":"sessionId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/jobs/{jobId}":{"get":{"operationId":"getJob","tags":["jobs"],"summary":"Get an async job's status and result","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["read"]},"responses":{"200":{"description":"Job status/result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/jobs/{jobId}/cancel":{"post":{"operationId":"cancelJob","tags":["jobs"],"summary":"Cancel an async job","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"]},"responses":{"200":{"description":"Cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"jobId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/workspace":{"post":{"operationId":"createWorkspace","tags":["workspace"],"summary":"Mint a workspace (project + imported source) in one call","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"projects":["write"],"media":["write"]},"x-x402":{"amount":"20000","deliverable":true,"maxTimeoutSeconds":900},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateRequest"}}}},"responses":{"202":{"description":"Workspace minted; source import enqueued.","content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string"},"mediaId":{"type":"string"}},"required":["projectId","mediaId"],"additionalProperties":false}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"20000"},"protocols":[{"x402":{}}]}}},"/v1/api-keys":{"post":{"operationId":"createApiKey","tags":["api-keys"],"summary":"Create a scoped API key (session credential only)","security":[{"bearerAuth":[]},{"x402":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"201":{"description":"Key created — the secret is returned ONCE.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"Unprocessable — invalid_composition / media_in_use / session_in_use / render_not_cancellable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/usage":{"get":{"operationId":"getUsage","tags":["billing"],"summary":"List metered usage events (the A2 usage ledger)","description":"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).","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"billing":["read"]},"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size (1..100), default 20. Out-of-range or unparseable clamps into the range.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"after","in":"query","required":false,"description":"Opaque cursor from the previous page's `pagination.nextCursor`. Forward-only.","schema":{"type":"string"}},{"name":"projectId","in":"query","required":false,"description":"Only events attributed to this project.","schema":{"type":"string"}},{"name":"jobId","in":"query","required":false,"description":"Only events produced by this job — how to answer \"did my failed render post a charge?\" for one run.","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"Period start, epoch milliseconds, INCLUSIVE.","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"name":"to","in":"query","required":false,"description":"Period end, epoch milliseconds, EXCLUSIVE.","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}}],"responses":{"200":{"description":"Paginated usage events.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageListResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/billing/plans":{"get":{"operationId":"getBillingPlans","tags":["billing"],"summary":"List the plan catalog: tiers, intervals, product ids, prices","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"responses":{"200":{"description":"Plan catalog.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlansResponse"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/billing/checkout":{"post":{"operationId":"createCheckout","tags":["billing"],"summary":"Start a hosted Stripe checkout for a plan/interval","description":"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`.","security":[{"bearerAuth":[]},{"x402":[]}],"x-permissions":{"billing":["write"]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}}},"responses":{"200":{"description":"Hosted Stripe checkout URL to open in a browser.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/v1/traces/{traceId}/scores":{"post":{"operationId":"scoreTrace","tags":["traces"],"summary":"Attach production scores to one of your director traces","description":"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.","security":[{"bearerAuth":[]},{"x402":[]}],"x-x402":"write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceScoresRequest"}}}},"responses":{"202":{"description":"Scores accepted and forwarded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TraceScoresResponse"}}}},"400":{"description":"Bad request — validation_error / invalid_cursor / invalid_query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid Authorization header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Payment required. Returned when the caller presents no API key on a priced operation: the body AND the `Payment-Required` header carry the x402 v2 challenge (accepted scheme, network, USDC asset, amount, payTo). Sign the EIP-3009 authorization and retry with a `PAYMENT-SIGNATURE` header. A KEYED caller sees this status instead when their plan lacks or has exhausted the feature (`billing_required`).","headers":{"Payment-Required":{"description":"Base64 x402 v2 PaymentRequired envelope — the same challenge as the body, for clients that read it off the header.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/X402PaymentRequired"}}}},"403":{"description":"Forbidden — permission insufficient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Resource not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Rate limited. Retry-After header present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Service unavailable — billing_unavailable / honest-503 for runtime deps.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"traceId","required":true}],"x-payment-info":{"price":{"mode":"fixed","currency":"USDC","amount":"10000"},"protocols":[{"x402":{}}]}}},"/openapi.json":{"get":{"tags":["health"],"summary":"OpenAPI 3.1 document for the v1 API","description":"Returns the generated OpenAPI 3.1 document. Unauthenticated so SDK tooling (Orval, Postman, redocly) can fetch without a key. Cacheable for 5 minutes.","operationId":"getOpenAPISpec","security":[],"responses":{"200":{"description":"Generated OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Malformed request (unlikely; included for completeness).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"Internal error generating the spec.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}}}