{"openapi":"3.1.0","info":{"title":"MediaBliss API","description":"Browser-based media / subtitle / AI-video SaaS API (modular monolith).\n\n**Auth:** session cookie (web app) or `Authorization: Bearer <api-key>` for the public `/v1` surface. Tenancy is enforced by Postgres RLS; plan entitlements gate premium features. **Webhooks** are signed (HMAC, `MB-Signature`). Most endpoints document their behaviour in the operation description below; see the Developer Guide for recipes.","contact":{"name":"MediaBliss","url":"https://docs.modkrib.com/"},"license":{"name":"Proprietary"},"version":"1.0.0"},"paths":{"/api/v1/jobs/demo":{"post":{"tags":["jobs"],"summary":"Start Demo Job","description":"Start a demo job for the caller's workspace and return its id (202 Accepted).\nRequires auth — the job is stamped with the principal's tenant and is only visible to\nthat tenant (RLS). The caller then opens the SSE stream below to watch it.\n\nWe generate the job_id HERE so we can hand it back to the browser AND pass it into the\nworkflow — guaranteeing the executor records progress on the very job the SSE stream is\nabout to follow. The job row is persisted (under the tenant's RLS context) BEFORE we\ntrigger work, so the worker's first step always finds it.","operationId":"start_demo_job_api_v1_jobs_demo_post","responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Start Demo Job Api V1 Jobs Demo Post"}}}}}}},"/api/v1/jobs/{job_id}/events":{"get":{"tags":["jobs"],"summary":"Job Events","description":"Stream a job's progress as Server-Sent Events (text/event-stream). Requires auth;\nthe stream is scoped to the caller's tenant (RLS), so you can only watch your own jobs.\n\nThe browser's `EventSource` (with credentials) consumes this and updates a progress bar.\n`stream_job_events` first REPLAYS the job's persisted history, then tails the live Redis\nchannel (seq-deduped), so connecting late still shows the full job. Ends at the terminal.","operationId":"job_events_api_v1_jobs__job_id__events_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets":{"post":{"tags":["media"],"summary":"Upload Asset","description":"Upload a media file into the caller's workspace via the active storage backend.\nOptionally files it into `project_id` (a folder the caller owns).\n\nThe bytes are staged to a temp file first so we can (a) ffprobe it for media facts and\n(b) hand a real fileobj to the backend — works the same for local and s3.","operationId":"upload_asset_api_v1_assets_post","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_asset_api_v1_assets_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Upload Asset Api V1 Assets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["media"],"summary":"List Assets","description":"List the caller's media assets (RLS-scoped). Optional `?project_id=` filters to a\nfolder; `?project_id=none` lists only uncategorised assets.","operationId":"list_assets_api_v1_assets_get","parameters":[{"name":"project_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Assets Api V1 Assets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}":{"patch":{"tags":["media"],"summary":"Update Asset","description":"Rename and/or move an asset between projects (both optional).","operationId":"update_asset_api_v1_assets__public_id__patch","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_PatchAssetBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Asset Api V1 Assets  Public Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["media"],"summary":"Delete Asset","description":"Delete an asset: remove the stored bytes from the active backend, then the DB row.\n\nWe delete bytes first (best-effort — a storage hiccup shouldn't strand the row), then\nthe row under RLS. Derived assets that referenced this one keep their dangling\nsource_asset_id (the editor already tolerates a missing source).","operationId":"delete_asset_api_v1_assets__public_id__delete","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Asset Api V1 Assets  Public Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/templates":{"get":{"tags":["media"],"summary":"List Caption Templates","description":"The karaoke caption templates a transcription can apply (the viral 'looks').","operationId":"list_caption_templates_api_v1_assets_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Caption Templates Api V1 Assets Templates Get"}}}}}}},"/api/v1/assets/{public_id}/transcribe":{"post":{"tags":["media"],"summary":"Transcribe Asset","description":"Kick off a durable transcription → karaoke `.ass` job for an asset, using the chosen\ncaption template (the wedge). `asr_engine` (LOC-1) selects whisper/deepgram/scribe (falls back\nto the configured default); `vocab` (GEN-1) is a comma-separated custom-vocabulary bias list.\nReturns a job_id streamed over /jobs/{id}/events.","operationId":"transcribe_asset_api_v1_assets__public_id__transcribe_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"template_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"}},{"name":"asr_engine","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asr Engine"}},{"name":"vocab","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vocab"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Transcribe Asset Api V1 Assets  Public Id  Transcribe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/burn":{"post":{"tags":["media"],"summary":"Burn Asset","description":"Burn a subtitle asset into a video asset (durable job). Returns a job_id to stream\nover /jobs/{id}/events. Both assets must belong to the caller (RLS-checked here).","operationId":"burn_asset_api_v1_assets__public_id__burn_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_BurnBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Burn Asset Api V1 Assets  Public Id  Burn Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/dub":{"post":{"tags":["media"],"summary":"Dub Asset","description":"Dub a video (doc 12): synthesize speech from a subtitle track, fit each line to its on-screen\nwindow, and mux it onto the video (durable job → job_id). Optionally translates first. TTS is\nprovider-gated (ElevenLabs when keyed; a local tone stand-in otherwise).","operationId":"dub_asset_api_v1_assets__public_id__dub_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_DubBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Dub Asset Api V1 Assets  Public Id  Dub Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/subtitle":{"get":{"tags":["media"],"summary":"Get Subtitle","description":"Return a subtitle asset's raw .ass text plus its source video (for the editor).\n\nThe editor renders the .ass over the source video with libass (JASSUB) and lets the\nuser edit cues. `source` is the asset transcription recorded in `source_asset_id`\n(or None if unknown / hand-uploaded) — the client previews/streams it by id.","operationId":"get_subtitle_api_v1_assets__public_id__subtitle_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Subtitle Api V1 Assets  Public Id  Subtitle Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["media"],"summary":"Save Subtitle","description":"Overwrite a subtitle asset's stored .ass with the editor's edited text.\n\nLight validation only (must be a non-empty ASS doc with an [Events] section) — we\ntrust libass to render whatever the client serializes. Writes back to the SAME\nstorage key (in-place edit) and updates the recorded byte size.","operationId":"save_subtitle_api_v1_assets__public_id__subtitle_put","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_SubtitleBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Save Subtitle Api V1 Assets  Public Id  Subtitle Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/reframe":{"post":{"tags":["media"],"summary":"Reframe Asset","description":"Kick off a smart reframe job for a video asset (subject-centred crop) to `aspect`\n(9:16 | 1:1 | 16:9, GEN-2). Returns a job_id to stream over /jobs/{id}/events; on success a\nnew \"_<aspect>.mp4\" appears.","operationId":"reframe_asset_api_v1_assets__public_id__reframe_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"aspect","in":"query","required":false,"schema":{"type":"string","default":"9:16","title":"Aspect"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reframe Asset Api V1 Assets  Public Id  Reframe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/transcode/presets":{"get":{"tags":["media"],"summary":"List Transcode Presets","description":"The encode presets a transcode can target (delivery H.264 tiers + ProRes/DNxHR masters).\nDrives the transcode picker in the UI.","operationId":"list_transcode_presets_api_v1_assets_transcode_presets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Transcode Presets Api V1 Assets Transcode Presets Get"}}}}}}},"/api/v1/assets/{public_id}/transcode":{"post":{"tags":["media"],"summary":"Transcode Asset","description":"Kick off a server transcode to a delivery tier or a ProRes/DNxHR master via the validated\ncommand engine. Returns a job_id streamed over /jobs/{id}/events; on success a new\n\"_<preset>.<ext>\" asset appears. The preset is validated here so a bad key 400s immediately.","operationId":"transcode_asset_api_v1_assets__public_id__transcode_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TranscodeBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Transcode Asset Api V1 Assets  Public Id  Transcode Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/remux":{"post":{"tags":["media"],"summary":"Remux Asset","description":"Rewrap a video into another container (MP4/MOV/MKV) with NO re-encode — fast (MED-6).\nReturns a job_id; on success a new \"_remux.<ext>\" asset appears.","operationId":"remux_asset_api_v1_assets__public_id__remux_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RemuxBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Remux Asset Api V1 Assets  Public Id  Remux Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/trim":{"post":{"tags":["media"],"summary":"Trim Asset","description":"Trim [start_s, end_s) (MED-6). `precise=false` (default) = fast keyframe-bounded stream-copy;\n`precise=true` = frame-accurate re-encode (exact in/out). Returns a job_id; on success a new\n\"_trim.<ext>\" asset appears.","operationId":"trim_asset_api_v1_assets__public_id__trim_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TrimBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Trim Asset Api V1 Assets  Public Id  Trim Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/concat":{"post":{"tags":["media"],"summary":"Concat Assets","description":"Join ≥2 video assets (in order) into one via the concat demuxer — stream-copy, no\nre-encode (MED-6). Parts must share codec/params (a concat-filter re-encode fallback is a\nfollow-up). Returns a job_id; on success a new \"_concat.<ext>\" asset appears.","operationId":"concat_assets_api_v1_assets_concat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ConcatBody"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Concat Assets Api V1 Assets Concat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/qc":{"post":{"tags":["media"],"summary":"Qc Asset","description":"Run a QC pass on a video asset (MED-8/9/10): VMAF/PSNR/SSIM vs a reference (defaults to the\nasset's source) + EBU R128 loudness + black/silence/freeze detection → a signed report stored\nas a job artifact. Returns a job_id; fetch the result with GET /assets/{id}/qc.","operationId":"qc_asset_api_v1_assets__public_id__qc_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_QCBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Qc Asset Api V1 Assets  Public Id  Qc Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["media"],"summary":"Get Qc Report","description":"Return the latest QC report for an asset (the signed JSON produced by a prior QC job), or\n404 if none has been run yet. The report carries VMAF/PSNR/SSIM, loudness, detection + verdict.","operationId":"get_qc_report_api_v1_assets__public_id__qc_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Qc Report Api V1 Assets  Public Id  Qc Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/loudnorm":{"post":{"tags":["media"],"summary":"Loudnorm Asset","description":"EBU R128 2-pass loudness-normalise a video's audio to `target_lufs` (MED-9), video copied.\nReturns a job_id; on success a new \"_loudnorm.<ext>\" asset appears.","operationId":"loudnorm_asset_api_v1_assets__public_id__loudnorm_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_LoudnormBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Loudnorm Asset Api V1 Assets  Public Id  Loudnorm Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/route":{"post":{"tags":["media"],"summary":"Route Operation","description":"Authoritative client-vs-server routing decision for a media op (doc 09 §2.2). The browser\ncalls this with its probed capabilities to confirm the fast path before running WebCodecs;\na headless caller (no client_caps) always routes to the server. Entitlements come from the\ncaller's plan (HEVC/E-AC-3/AC-4 gating).","operationId":"route_operation_api_v1_assets_route_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RouteBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Route Operation Api V1 Assets Route Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/inspect":{"get":{"tags":["media"],"summary":"Inspect Asset","description":"Full FFprobe → MediaInfo report for an asset (MED-7): format + per-stream video/audio/\nsubtitle detail (codec/profile/pix_fmt/bit-depth/colour/HDR) + chapters. Downloads the bytes\nto a temp file and runs the inspection. This is the Sprint-7 demo's 'inspect the report'.","operationId":"inspect_asset_api_v1_assets__public_id__inspect_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Inspect Asset Api V1 Assets  Public Id  Inspect Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/export":{"get":{"tags":["media"],"summary":"Export Subtitle","description":"Convert a subtitle asset to a delivery format (srt/vtt/ttml/imsc/ebu-tt-d) and stream it as\na download (LOC-8). Routes through the canonical model (doc 10 §4.1); `X-Subtitle-Losses` lists\ndropped features. When `profile` is given (netflix/bbc/amazon/disney/ebu), the document is\ncompliance-checked first (LOC-5) and a non-conforming export is BLOCKED with 422 + the violation\nlist, unless `force=true`.","operationId":"export_subtitle_api_v1_assets__public_id__export_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"srt","title":"Format"}},{"name":"profile","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Force"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/compliance":{"get":{"tags":["media"],"summary":"Check Compliance","description":"Run the compliance validator (LOC-5) on a subtitle against a profile (netflix/bbc/amazon/\ndisney/ebu) → the violation report (CPS/WPM/line-length/count/duration/gap/overlap). Drives the\ngrid editor's live validation + the pre-export gate.","operationId":"check_compliance_api_v1_assets__public_id__compliance_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"profile","in":"query","required":false,"schema":{"type":"string","default":"netflix","title":"Profile"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Check Compliance Api V1 Assets  Public Id  Compliance Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/coedit":{"get":{"tags":["media"],"summary":"Coedit Suggestions","description":"AI co-editor (doc 12 §9): propose concrete fixes for a subtitle's compliance violations\n(rebreak / extend / trim / split / nudge-gap), each a reviewable suggestion the editor can\naccept. Rule-based + deterministic (works without any API key); an LLM rewrite is layered when\n``anthropic_api_key`` is configured.","operationId":"coedit_suggestions_api_v1_assets__public_id__coedit_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}},{"name":"profile","in":"query","required":false,"schema":{"type":"string","default":"netflix","title":"Profile"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Coedit Suggestions Api V1 Assets  Public Id  Coedit Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/sdh":{"post":{"tags":["media"],"summary":"Generate Sdh","description":"Generate an SDH (deaf/hard-of-hearing) version of a subtitle (LOC-7): speaker labels + the\nnon-speech-cue insertion hook → a new \"<name>.sdh.ass\" subtitle asset. Synchronous (pure text).","operationId":"generate_sdh_api_v1_assets__public_id__sdh_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Generate Sdh Api V1 Assets  Public Id  Sdh Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/translate/providers":{"get":{"tags":["media"],"summary":"Translate Providers","description":"Which translation providers are configured/available + the ASR engines (drives the UI).","operationId":"translate_providers_api_v1_assets_translate_providers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Translate Providers Api V1 Assets Translate Providers Get"}}}}}}},"/api/v1/assets/{public_id}/translate":{"post":{"tags":["media"],"summary":"Translate Subtitle","description":"Translate a subtitle asset to `target_lang` via the MT router (LOC-2) → a new subtitle asset.\nReturns a job_id; on success a new \"<name>.<lang>.ass\" appears, ready for the editor + export.","operationId":"translate_subtitle_api_v1_assets__public_id__translate_post","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TranslateBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Translate Subtitle Api V1 Assets  Public Id  Translate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{public_id}/content":{"get":{"tags":["media"],"summary":"Asset Content","description":"Stream an asset's bytes from the active backend (RLS ensures it's the caller's).","operationId":"asset_content_api_v1_assets__public_id__content_get","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects":{"get":{"tags":["projects"],"summary":"List Projects","description":"List the caller's projects with asset counts (RLS-scoped).","operationId":"list_projects_api_v1_projects_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Projects Api V1 Projects Get"}}}}}},"post":{"tags":["projects"],"summary":"Create Project","description":"Create a project in the caller's workspace.","operationId":"create_project_api_v1_projects_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__modules__projects__router___CreateBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Project Api V1 Projects Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/projects/{public_id}":{"patch":{"tags":["projects"],"summary":"Rename Project","description":"Rename a project (404 if it isn't the caller's).","operationId":"rename_project_api_v1_projects__public_id__patch","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RenameBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Rename Project Api V1 Projects  Public Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Delete Project","description":"Delete a project; its assets become uncategorised (not deleted).","operationId":"delete_project_api_v1_projects__public_id__delete","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Project Api V1 Projects  Public Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspace/members":{"get":{"tags":["workspace"],"summary":"List Members","description":"List the workspace's members and their roles (owner only).","operationId":"list_members_api_v1_workspace_members_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Members Api V1 Workspace Members Get"}}}}}}},"/api/v1/workspace/members/{user_id}":{"patch":{"tags":["workspace"],"summary":"Change Role","description":"Change a member's role (owner only). Can't demote the workspace's last owner.","operationId":"change_role_api_v1_workspace_members__user_id__patch","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RoleBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Change Role Api V1 Workspace Members  User Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["workspace"],"summary":"Remove Member","description":"Remove a member from the workspace (owner only). Can't remove the last owner.","operationId":"remove_member_api_v1_workspace_members__user_id__delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Remove Member Api V1 Workspace Members  User Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspace/invites":{"get":{"tags":["workspace"],"summary":"List Invites","description":"List pending invites for the workspace (owner only).","operationId":"list_invites_api_v1_workspace_invites_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Invites Api V1 Workspace Invites Get"}}}}}},"post":{"tags":["workspace"],"summary":"Create Invite","description":"Invite an email to the workspace at a role (owner only). The invite is consumed\nwhen that email next signs in. Re-inviting updates the pending role.","operationId":"create_invite_api_v1_workspace_invites_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_InviteBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Invite Api V1 Workspace Invites Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workspace/invites/{invite_id}":{"delete":{"tags":["workspace"],"summary":"Revoke Invite","description":"Revoke a pending invite (owner only).","operationId":"revoke_invite_api_v1_workspace_invites__invite_id__delete","parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","title":"Invite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Invite Api V1 Workspace Invites  Invite Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/chapters/detect":{"post":{"tags":["chapters"],"summary":"Detect Chapters","description":"Kick off AI chapter detection for a video (durable job). Streams over /jobs/{id}/events;\non success the default chapter set is replaced and GET /chapters returns it.","operationId":"detect_chapters_api_v1_assets__video_id__chapters_detect_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Detect Chapters Api V1 Assets  Video Id  Chapters Detect Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/chapters":{"get":{"tags":["chapters"],"summary":"Get Chapters","description":"The default chapter set + ordered markers for the editor (empty list if none yet).","operationId":"get_chapters_api_v1_assets__video_id__chapters_get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Chapters Api V1 Assets  Video Id  Chapters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["chapters"],"summary":"Save Chapters","description":"Save the edited markers (manual editor). Sorts by start, re-derives idx + end_ms (next\nstart / video duration), creates the default set if there isn't one, and marks it 'mixed'\n(a human has touched it). The whole working set is replaced — simple + correct for one user.","operationId":"save_chapters_api_v1_assets__video_id__chapters_put","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_SaveChaptersBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Save Chapters Api V1 Assets  Video Id  Chapters Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/chapters/embed":{"post":{"tags":["chapters"],"summary":"Embed Chapters","description":"Mux the default chapter set into a new MP4 (durable job) — CHAP-6.","operationId":"embed_chapters_api_v1_assets__video_id__chapters_embed_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Embed Chapters Api V1 Assets  Video Id  Chapters Embed Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/chapters/export":{"get":{"tags":["chapters"],"summary":"Export Chapters","description":"Render the default set to a text export. `youtube` → description timestamps; `webvtt` →\na chapters track. Validation issues for the profile are returned in the `X-Chapter-Issues`\nheader so the UI can warn (e.g. YouTube needs ≥3 chapters, each ≥10 s).","operationId":"export_chapters_api_v1_assets__video_id__chapters_export_get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(youtube|webvtt)$","default":"youtube","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/chapters/candidates":{"get":{"tags":["chapters"],"summary":"Chapter Candidates","description":"Scene-cut + silence timestamps (ms) for the editor's magnetic-snap guides (doc 30 §3.1).\nRuns the two ffmpeg analysis passes on demand; best-effort with a timeout so a long video\ndoesn't hang the request (returns whatever it found).","operationId":"chapter_candidates_api_v1_assets__video_id__chapters_candidates_get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Chapter Candidates Api V1 Assets  Video Id  Chapters Candidates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/plans":{"get":{"tags":["billing"],"summary":"List Plans","description":"The full plan → entitlement matrix (doc 17 §3) — drives the pricing/upgrade UI.","operationId":"list_plans_api_v1_billing_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Plans Api V1 Billing Plans Get"}}}}}}},"/api/v1/billing/me":{"get":{"tags":["billing"],"summary":"My Billing","description":"The caller's current plan tier, effective entitlements, and this period's usage.","operationId":"my_billing_api_v1_billing_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response My Billing Api V1 Billing Me Get"}}}}}}},"/api/v1/billing/plan":{"put":{"tags":["billing"],"summary":"Set Plan","description":"Set the tenant's plan tier (owner-only; payments are handled out of band by Paddle/Stripe\nwebhooks in prod — this is the entitlement side). Validates the tier.","operationId":"set_plan_api_v1_billing_plan_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_SetPlanBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Set Plan Api V1 Billing Plan Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout","description":"Start a subscription checkout for ``tier`` (owner-only). Returns the hosted-checkout URL the\nbrowser is sent to. Config-gated: with no provider key set, returns a dev-stub URL so the flow is\nexercisable locally — the operator then POSTs a synthetic webhook to flip the plan.","operationId":"create_checkout_api_v1_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_CheckoutBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Checkout Api V1 Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/webhooks/stripe":{"post":{"tags":["billing"],"summary":"Stripe Webhook","description":"Stripe subscription-lifecycle webhook (unauthenticated; trust comes from the signature).","operationId":"stripe_webhook_api_v1_billing_webhooks_stripe_post","parameters":[{"name":"Stripe-Signature","in":"header","required":false,"schema":{"type":"string","default":"","title":"Stripe-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Stripe Webhook Api V1 Billing Webhooks Stripe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/billing/webhooks/paddle":{"post":{"tags":["billing"],"summary":"Paddle Webhook","description":"Paddle Billing subscription webhook (unauthenticated; trust comes from the signature).","operationId":"paddle_webhook_api_v1_billing_webhooks_paddle_post","parameters":[{"name":"Paddle-Signature","in":"header","required":false,"schema":{"type":"string","default":"","title":"Paddle-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Paddle Webhook Api V1 Billing Webhooks Paddle Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review":{"get":{"tags":["review"],"summary":"List Reviews","operationId":"list_reviews_api_v1_review_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Reviews Api V1 Review Get"}}}}}},"post":{"tags":["review"],"summary":"Create Review","description":"Open a review task for a subtitle asset (starts at the ASR stage).","operationId":"create_review_api_v1_review_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__modules__review__router___CreateBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Review Api V1 Review Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review/{rid}":{"get":{"tags":["review"],"summary":"Get Review","operationId":"get_review_api_v1_review__rid__get","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"string","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Review Api V1 Review  Rid  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review/{rid}/advance":{"post":{"tags":["review"],"summary":"Advance Review","description":"Advance a task to the next stage. Advancing PAST QC runs the compliance gate: a blocked\n(non-conforming) subtitle cannot be approved (doc 27 Theme #3, LOC-5).","operationId":"advance_review_api_v1_review__rid__advance_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"string","title":"Rid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MoveBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Advance Review Api V1 Review  Rid  Advance Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review/{rid}/reject":{"post":{"tags":["review"],"summary":"Reject Review","description":"Reject from a QC/approve gate back to the edit stage (the rework loop).","operationId":"reject_review_api_v1_review__rid__reject_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"string","title":"Rid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MoveBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Reject Review Api V1 Review  Rid  Reject Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review/{rid}/lock":{"post":{"tags":["review"],"summary":"Lock Review","description":"Take the single-holder edit lock (refused if another user holds it).","operationId":"lock_review_api_v1_review__rid__lock_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"string","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lock Review Api V1 Review  Rid  Lock Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/review/{rid}/unlock":{"post":{"tags":["review"],"summary":"Unlock Review","description":"Release the edit lock (only the holder, or an owner, may release).","operationId":"unlock_review_api_v1_review__rid__unlock_post","parameters":[{"name":"rid","in":"path","required":true,"schema":{"type":"string","title":"Rid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Unlock Review Api V1 Review  Rid  Unlock Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/platform/api-keys":{"get":{"tags":["platform"],"summary":"List Api Keys","operationId":"list_api_keys_api_v1_platform_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Api Keys Api V1 Platform Api Keys Get"}}}}}},"post":{"tags":["platform"],"summary":"Create Api Key","description":"Mint a scoped API key. The plaintext secret is returned ONCE — only its hash is stored.","operationId":"create_api_key_api_v1_platform_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_KeyBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Api Key Api V1 Platform Api Keys Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/platform/api-keys/{kid}":{"delete":{"tags":["platform"],"summary":"Revoke Api Key","operationId":"revoke_api_key_api_v1_platform_api_keys__kid__delete","parameters":[{"name":"kid","in":"path","required":true,"schema":{"type":"string","title":"Kid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Api Key Api V1 Platform Api Keys  Kid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/platform/webhooks":{"get":{"tags":["platform"],"summary":"List Webhooks","operationId":"list_webhooks_api_v1_platform_webhooks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Webhooks Api V1 Platform Webhooks Get"}}}}}},"post":{"tags":["platform"],"summary":"Create Webhook","description":"Register a webhook endpoint. The signing secret is returned ONCE (verify deliveries with it).","operationId":"create_webhook_api_v1_platform_webhooks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_WebhookBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Webhook Api V1 Platform Webhooks Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/platform/webhooks/{wid}":{"delete":{"tags":["platform"],"summary":"Delete Webhook","operationId":"delete_webhook_api_v1_platform_webhooks__wid__delete","parameters":[{"name":"wid","in":"path","required":true,"schema":{"type":"string","title":"Wid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Webhook Api V1 Platform Webhooks  Wid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/v1/whoami":{"get":{"tags":["public-api"],"summary":"Whoami","description":"Smoke endpoint for the SDK quickstart — confirms the key works + shows its scopes/tenant.","operationId":"whoami_api_v1_v1_whoami_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Whoami Api V1 V1 Whoami Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/v1/transcribe":{"post":{"tags":["public-api"],"summary":"Public Transcribe","description":"Public API: kick off a transcription job (requires the ``jobs:create`` scope). Returns a\njob_id the caller polls via GET /v1/jobs/{id} (or receives a job.succeeded webhook).","operationId":"public_transcribe_api_v1_v1_transcribe_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_PublicTranscribeBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Transcribe Api V1 V1 Transcribe Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/v1/jobs/{job_id}":{"get":{"tags":["public-api"],"summary":"Public Job Status","description":"Public API: job status (requires the ``read`` scope).","operationId":"public_job_status_api_v1_v1_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Job Status Api V1 V1 Jobs  Job Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/publish/tiktok/status":{"get":{"tags":["publish"],"summary":"Tiktok Status","description":"Whether publishing is configured at all, and whether THIS user has connected.","operationId":"tiktok_status_api_v1_publish_tiktok_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Tiktok Status Api V1 Publish Tiktok Status Get"}}}}}}},"/api/v1/publish/tiktok/connect":{"get":{"tags":["publish"],"summary":"Tiktok Connect","description":"Begin the OAuth flow: stash a CSRF state in a cookie and redirect to TikTok consent.","operationId":"tiktok_connect_api_v1_publish_tiktok_connect_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/publish/tiktok/callback":{"get":{"tags":["publish"],"summary":"Tiktok Callback","description":"OAuth redirect target: verify state, exchange the code, store sealed tokens, bounce back.","operationId":"tiktok_callback_api_v1_publish_tiktok_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/publish/tiktok":{"delete":{"tags":["publish"],"summary":"Tiktok Disconnect","description":"Drop the caller's stored TikTok tokens.","operationId":"tiktok_disconnect_api_v1_publish_tiktok_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Tiktok Disconnect Api V1 Publish Tiktok Delete"}}}}}}},"/api/v1/publish/platforms":{"get":{"tags":["publish"],"summary":"List Platforms","description":"Every connector's id/label/enabled + capability hints, plus which the caller has connected.\nDrives the publishing UI's connect buttons + per-platform caption limits.","operationId":"list_platforms_api_v1_publish_platforms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Platforms Api V1 Publish Platforms Get"}}}}}}},"/api/v1/publish/{platform}/connect":{"get":{"tags":["publish"],"summary":"Social Connect","description":"Begin OAuth for a platform: stash a CSRF state cookie + redirect to the provider's consent.","operationId":"social_connect_api_v1_publish__platform__connect_get","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/publish/{platform}/callback":{"get":{"tags":["publish"],"summary":"Social Callback","description":"OAuth redirect target: verify state, exchange the code, store sealed tokens, bounce back.","operationId":"social_callback_api_v1_publish__platform__callback_get","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}},{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/publish/{platform}":{"delete":{"tags":["publish"],"summary":"Social Disconnect","description":"Drop the caller's stored tokens for a platform.","operationId":"social_disconnect_api_v1_publish__platform__delete","parameters":[{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Social Disconnect Api V1 Publish  Platform  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/publish/scheduled":{"get":{"tags":["publish"],"summary":"List Scheduled","description":"The workspace's scheduled + recent posts (newest first).","operationId":"list_scheduled_api_v1_publish_scheduled_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Scheduled Api V1 Publish Scheduled Get"}}}}}}},"/api/v1/publish/scheduled/{post_id}":{"delete":{"tags":["publish"],"summary":"Cancel Scheduled","description":"Cancel a still-scheduled post (no-op if already publishing/published).","operationId":"cancel_scheduled_api_v1_publish_scheduled__post_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"string","title":"Post Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cancel Scheduled Api V1 Publish Scheduled  Post Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/publish/tiktok":{"post":{"tags":["publish"],"summary":"Publish To Tiktok","description":"Kick off a durable TikTok publish job for a video (requires a connection).","operationId":"publish_to_tiktok_api_v1_assets__video_id__publish_tiktok_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_PublishBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Publish To Tiktok Api V1 Assets  Video Id  Publish Tiktok Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/assets/{video_id}/schedule":{"post":{"tags":["publish"],"summary":"Schedule Post","description":"Queue a video to publish to one or more platforms now or at a future time.\n\nValidates the targets against what's enabled + connected (rejecting the rest with a reason),\npersists a scheduled_posts row, and — if it's due now — fires the publish workflow immediately\nso the user doesn't wait for the next sweeper tick.","operationId":"schedule_post_api_v1_assets__video_id__schedule_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","title":"Video Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ScheduleBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Schedule Post Api V1 Assets  Video Id  Schedule Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whitelabel/domains":{"get":{"tags":["whitelabel"],"summary":"List Domains","operationId":"list_domains_api_v1_whitelabel_domains_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Domains Api V1 Whitelabel Domains Get"}}}}}},"post":{"tags":["whitelabel"],"summary":"Add Domain","description":"Claim a custom domain. Returns the verification token + the well-known path to serve it at.","operationId":"add_domain_api_v1_whitelabel_domains_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_DomainBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Add Domain Api V1 Whitelabel Domains Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whitelabel/domains/{did}/verify":{"post":{"tags":["whitelabel"],"summary":"Verify Domain","description":"Fetch the challenge token from the domain and mark it verified if it matches.\n\nThe domain must serve the exact token over HTTPS at the well-known path. Until it does, the\ndomain stays inert (won't resolve).","operationId":"verify_domain_api_v1_whitelabel_domains__did__verify_post","parameters":[{"name":"did","in":"path","required":true,"schema":{"type":"string","title":"Did"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Verify Domain Api V1 Whitelabel Domains  Did  Verify Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whitelabel/domains/{did}":{"delete":{"tags":["whitelabel"],"summary":"Delete Domain","operationId":"delete_domain_api_v1_whitelabel_domains__did__delete","parameters":[{"name":"did","in":"path","required":true,"schema":{"type":"string","title":"Did"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Domain Api V1 Whitelabel Domains  Did  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whitelabel/branding":{"get":{"tags":["whitelabel"],"summary":"Get Branding","operationId":"get_branding_api_v1_whitelabel_branding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Branding Api V1 Whitelabel Branding Get"}}}}}},"put":{"tags":["whitelabel"],"summary":"Set Branding","description":"Update branding (owner-only, gated). Only provided fields change.","operationId":"set_branding_api_v1_whitelabel_branding_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_BrandingBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Set Branding Api V1 Whitelabel Branding Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/whitelabel/resolve":{"get":{"tags":["whitelabel"],"summary":"Resolve","description":"host → {tenant_id, branding}. Unknown/unverified host → default MediaBliss branding with\ntenant_id null. UNauthenticated (the edge themes the login page before any session exists).","operationId":"resolve_api_v1_whitelabel_resolve_get","parameters":[{"name":"host","in":"query","required":true,"schema":{"type":"string","title":"Host"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Resolve Api V1 Whitelabel Resolve Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/ServiceProviderConfig":{"get":{"tags":["scim"],"summary":"Service Provider Config","operationId":"service_provider_config_api_v1_scim_v2_ServiceProviderConfig_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/ResourceTypes":{"get":{"tags":["scim"],"summary":"Resource Types","operationId":"resource_types_api_v1_scim_v2_ResourceTypes_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/Schemas":{"get":{"tags":["scim"],"summary":"Schemas","operationId":"schemas_api_v1_scim_v2_Schemas_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/Users":{"get":{"tags":["scim"],"summary":"List Users","description":"List Users, honoring the ``userName eq \"x\"`` filter Okta/Azure use to check existence.","operationId":"list_users_api_v1_scim_v2_Users_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["scim"],"summary":"Create User","description":"Provision a user → ensures the app user + an active membership.","operationId":"create_user_api_v1_scim_v2_Users_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/Users/{scim_id}":{"get":{"tags":["scim"],"summary":"Get User","operationId":"get_user_api_v1_scim_v2_Users__scim_id__get","parameters":[{"name":"scim_id","in":"path","required":true,"schema":{"type":"string","title":"Scim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["scim"],"summary":"Replace User","operationId":"replace_user_api_v1_scim_v2_Users__scim_id__put","parameters":[{"name":"scim_id","in":"path","required":true,"schema":{"type":"string","title":"Scim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["scim"],"summary":"Patch User","description":"PATCH — the dominant deprovision path is a replace of ``active``.","operationId":"patch_user_api_v1_scim_v2_Users__scim_id__patch","parameters":[{"name":"scim_id","in":"path","required":true,"schema":{"type":"string","title":"Scim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["scim"],"summary":"Delete User","description":"SCIM DELETE = deprovision (suspends the membership, drops the SCIM resource).","operationId":"delete_user_api_v1_scim_v2_Users__scim_id__delete","parameters":[{"name":"scim_id","in":"path","required":true,"schema":{"type":"string","title":"Scim Id"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/Groups":{"get":{"tags":["scim"],"summary":"List Groups","description":"Read-only Groups derived from membership roles (owner/admin/member). Writable group push is a\ndocumented follow-up — we have no standalone group store, roles ARE the groups.","operationId":"list_groups_api_v1_scim_v2_Groups_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/v2/Groups/{role}":{"get":{"tags":["scim"],"summary":"Get Group","operationId":"get_group_api_v1_scim_v2_Groups__role__get","parameters":[{"name":"role","in":"path","required":true,"schema":{"type":"string","title":"Role"}},{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/tokens":{"get":{"tags":["scim-admin"],"summary":"List Tokens","operationId":"list_tokens_api_v1_scim_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Tokens Api V1 Scim Tokens Get"}}}}}},"post":{"tags":["scim-admin"],"summary":"Create Token","description":"Mint a SCIM bearer token (owner-only, requires the ``sso`` entitlement). Shown once.","operationId":"create_token_api_v1_scim_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TokenBody"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Token Api V1 Scim Tokens Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/scim/tokens/{tid}":{"delete":{"tags":["scim-admin"],"summary":"Revoke Token","operationId":"revoke_token_api_v1_scim_tokens__tid__delete","parameters":[{"name":"tid","in":"path","required":true,"schema":{"type":"string","title":"Tid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Token Api V1 Scim Tokens  Tid  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/collab/token":{"get":{"tags":["collab"],"summary":"Collab Token","description":"Mint a room token for collaborating on ``asset_id`` (must be a real asset in this tenant).","operationId":"collab_token_api_v1_collab_token_get","parameters":[{"name":"asset_id","in":"query","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Collab Token Api V1 Collab Token Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/whoami":{"get":{"tags":["ops"],"summary":"Whoami","description":"Confirm operator access + show the caller's operator role.","operationId":"whoami_api_v1_ops_whoami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Whoami Api V1 Ops Whoami Get"}}}}}}},"/api/v1/ops/tenants":{"get":{"tags":["ops"],"summary":"List Tenants","description":"Every tenant with plan tier/status, member count, suspension flag.","operationId":"list_tenants_api_v1_ops_tenants_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Tenants Api V1 Ops Tenants Get"}}}}}}},"/api/v1/ops/tenants/{tenant_id}":{"get":{"tags":["ops"],"summary":"Get Tenant","description":"Full tenant detail: plan, entitlement overrides, members, and current-period usage.","operationId":"get_tenant_api_v1_ops_tenants__tenant_id__get","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Tenant Api V1 Ops Tenants  Tenant Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/tenants/{tenant_id}/tier":{"post":{"tags":["ops"],"summary":"Set Tier","description":"Change a tenant's plan tier (ops+). Audited with the supplied reason.","operationId":"set_tier_api_v1_ops_tenants__tenant_id__tier_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TierBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Tier Api V1 Ops Tenants  Tenant Id  Tier Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/tenants/{tenant_id}/entitlement":{"post":{"tags":["ops"],"summary":"Set Entitlement","description":"Set or clear a single per-tenant entitlement override (ops+). Audited.","operationId":"set_entitlement_api_v1_ops_tenants__tenant_id__entitlement_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_OverrideBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Entitlement Api V1 Ops Tenants  Tenant Id  Entitlement Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/tenants/{tenant_id}/suspend":{"post":{"tags":["ops"],"summary":"Set Suspended","description":"Suspend / reactivate a whole workspace (ops+). Audited.","operationId":"set_suspended_api_v1_ops_tenants__tenant_id__suspend_post","parameters":[{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string","title":"Tenant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_SuspendBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Set Suspended Api V1 Ops Tenants  Tenant Id  Suspend Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/storage":{"get":{"tags":["ops"],"summary":"Get Storage","description":"The active storage backend, the env default, and a health probe of each (operator-only).","operationId":"get_storage_api_v1_ops_storage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Storage Api V1 Ops Storage Get"}}}}}},"post":{"tags":["ops"],"summary":"Set Storage","description":"Switch the instance-wide active storage backend (ops+). Refuses an unhealthy target so\nuploads don't strand; existing objects are NOT migrated (only NEW uploads move). Audited.","operationId":"set_storage_api_v1_ops_storage_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_StorageBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Set Storage Api V1 Ops Storage Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/settings":{"get":{"tags":["ops"],"summary":"Get Settings","description":"Every operator-configurable setting with its category, whether it's set, and its source\n(db|env|unset). Secret VALUES are never returned — only whether one is configured.","operationId":"get_settings_api_v1_ops_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Settings Api V1 Ops Settings Get"}}}}}},"post":{"tags":["ops"],"summary":"Set Setting","description":"Set one credential/setting (superadmin; secrets sealed at rest). Audited WITHOUT the value.","operationId":"set_setting_api_v1_ops_settings_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_SettingBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Set Setting Api V1 Ops Settings Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/settings/{key}":{"delete":{"tags":["ops"],"summary":"Clear Setting","description":"Clear a setting's DB override so it falls back to .env (superadmin). Audited.","operationId":"clear_setting_api_v1_ops_settings__key__delete","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Clear Setting Api V1 Ops Settings  Key  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/billing/events":{"get":{"tags":["ops"],"summary":"Billing Events","description":"The most recent provider webhook events across all tenants (reconciliation).","operationId":"billing_events_api_v1_ops_billing_events_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Billing Events Api V1 Ops Billing Events Get"}}}}}}},"/api/v1/ops/stats":{"get":{"tags":["ops"],"summary":"Stats","description":"Aggregate platform metrics for the operator dashboard.","operationId":"stats_api_v1_ops_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Stats Api V1 Ops Stats Get"}}}}}}},"/api/v1/ops/users":{"get":{"tags":["ops"],"summary":"List Users","description":"List/search users by email, with their active-workspace count + suspension flag.","operationId":"list_users_api_v1_ops_users_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Users Api V1 Ops Users Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/users/{user_id}/suspend":{"post":{"tags":["ops"],"summary":"Suspend User","description":"Globally suspend/reactivate a user (ops+). A suspended user can sign in but every tenant\nroute 403s (enforced in current_principal). Audited.","operationId":"suspend_user_api_v1_ops_users__user_id__suspend_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_UserSuspendBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Suspend User Api V1 Ops Users  User Id  Suspend Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/users/{user_id}/impersonate":{"post":{"tags":["ops"],"summary":"Impersonate User","description":"Begin a \"log in as user\" session (superadmin only, audited). Mints a signed, 1-hour\nimpersonation cookie that `current_principal` honours ahead of the operator's own session, so\nthe operator's browser acts AS the target across the apps (with an always-visible banner +\none-click exit via /auth/impersonate/stop). Refuses to impersonate a suspended user (reactivate\nfirst) — the principal would 403 on every tenant route anyway.","operationId":"impersonate_user_api_v1_ops_users__user_id__impersonate_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ImpersonateBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/operators":{"get":{"tags":["ops"],"summary":"List Operators","description":"The platform-operator allow-list.","operationId":"list_operators_api_v1_ops_operators_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Operators Api V1 Ops Operators Get"}}}}}},"post":{"tags":["ops"],"summary":"Grant Operator","description":"Elevate any user to operator, or change their role (superadmin only). Audited. Guards against\ndemoting the last superadmin (would lock everyone out of console mutations).","operationId":"grant_operator_api_v1_ops_operators_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_OperatorBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Grant Operator Api V1 Ops Operators Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/operators/{email}":{"delete":{"tags":["ops"],"summary":"Revoke Operator","description":"Revoke operator access (superadmin only). Refuses to remove the last superadmin. Audited.","operationId":"revoke_operator_api_v1_ops_operators__email__delete","parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string","title":"Email"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Operator Api V1 Ops Operators  Email  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/ops/audit":{"get":{"tags":["ops"],"summary":"Audit Log","description":"The operator audit trail (optionally filtered to one tenant).","operationId":"audit_log_api_v1_ops_audit_get","parameters":[{"name":"tenant_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tenant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Audit Log Api V1 Ops Audit Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/help/ask":{"post":{"tags":["help"],"summary":"Ask","description":"Answer a product question, grounded in (and citing) the reference docs.","operationId":"ask_api_v1_help_ask_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"get":{"tags":["auth"],"summary":"Login","description":"Send the browser to the AuthKit hosted login page. `redirect_uri` is built from the\nincoming host so both localhost and the LAN IP / prod api host work (each registered in\nWorkOS). `return_to` (the web app's own origin) rides along in the signed state so the\ncallback can bounce back to the SAME origin the login started on (host-adaptive).","operationId":"login_api_v1_auth_login_get","parameters":[{"name":"return_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Return To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/callback":{"get":{"tags":["auth"],"summary":"Auth Callback","description":"AuthKit redirects here after login. Verify state, exchange the code, mirror the\nuser + provision their workspace, set the session cookie, and bounce to the web app.","operationId":"auth_callback_api_v1_auth_callback_get","parameters":[{"name":"code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/magic/start":{"post":{"tags":["auth"],"summary":"Magic Start","description":"Email a one-time sign-in code to the address (passwordless). Always returns\n`{sent: true}` — we don't reveal whether the email exists.","operationId":"magic_start_api_v1_auth_magic_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MagicStart"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Magic Start Api V1 Auth Magic Start Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/magic/verify":{"post":{"tags":["auth"],"summary":"Magic Verify","description":"Verify an (email, code) pair, establish the session (same cookie as the callback),\nand return the principal — so the web app can update its UI without a redirect.","operationId":"magic_verify_api_v1_auth_magic_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_MagicVerify"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/e2e-login":{"post":{"tags":["auth"],"summary":"E2E Login","description":"TEST-ONLY login for the Alpha-gate Playwright loop. 404 unless E2E_AUTH_SECRET is set;\n403 unless the request carries it in `X-E2E-Auth`. Mirrors a fixed test user + workspace\n(the same path WorkOS login uses) and sets a signed e2e cookie. NEVER enabled in prod.","operationId":"e2e_login_api_v1_auth_e2e_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/me":{"get":{"tags":["auth"],"summary":"Me","description":"Return the logged-in user + active workspace, or `{authenticated: false}`.","operationId":"me_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Me Api V1 Auth Me Get"}}}}}}},"/api/v1/auth/impersonate/stop":{"post":{"tags":["auth"],"summary":"Impersonate Stop","description":"Exit an impersonation session by clearing the impersonation cookie — the operator's own\nsession cookie is untouched, so they drop straight back to being themselves. No role gate:\nholding the cookie is sufficient (and the whole point is to always be able to step back out).\nReturns the web app origin so the UI can bounce back to a sensible place.","operationId":"impersonate_stop_api_v1_auth_impersonate_stop_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"End the WorkOS session and clear our cookie. Returns the WorkOS logout URL the web\napp should redirect the browser to (completes sign-out on WorkOS's side too). `return_to`\n(the web app's origin, allow-list validated) keeps sign-out host-adaptive like login.","operationId":"logout_api_v1_auth_logout_post","parameters":[{"name":"return_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Return To"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["meta"],"summary":"Health","description":"Liveness probe — tiny, dependency-free payload for Docker/systemd/LB checks.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Health Health Get"}}}}}}},"/api/v1":{"get":{"tags":["meta"],"summary":"Api Root","description":"Root of the versioned public API surface (architecture doc 08).","operationId":"api_root_api_v1_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Api Root Api V1 Get"}}}}}}}},"components":{"schemas":{"AskRequest":{"properties":{"question":{"type":"string","maxLength":2000,"minLength":3,"title":"Question"}},"type":"object","required":["question"],"title":"AskRequest"},"AskResponse":{"properties":{"answer":{"type":"string","title":"Answer"},"citations":{"items":{"$ref":"#/components/schemas/Citation"},"type":"array","title":"Citations"},"grounded":{"type":"boolean","title":"Grounded"}},"type":"object","required":["answer","citations","grounded"],"title":"AskResponse"},"Body_upload_asset_api_v1_assets_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"},"project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"}},"type":"object","required":["file"],"title":"Body_upload_asset_api_v1_assets_post"},"Citation":{"properties":{"source":{"type":"string","title":"Source"},"heading":{"type":"string","title":"Heading"}},"type":"object","required":["source","heading"],"title":"Citation"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"_BrandingBody":{"properties":{"product_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Product Name"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"favicon_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Favicon Url"},"primary_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Color"},"accent_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accent Color"},"support_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Support Email"},"custom_css":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Css"}},"type":"object","title":"_BrandingBody"},"_BurnBody":{"properties":{"subtitle_asset_id":{"type":"string","title":"Subtitle Asset Id"}},"type":"object","required":["subtitle_asset_id"],"title":"_BurnBody"},"_CheckoutBody":{"properties":{"tier":{"type":"string","title":"Tier"},"provider":{"type":"string","title":"Provider","default":"paddle"}},"type":"object","required":["tier"],"title":"_CheckoutBody"},"_ConcatBody":{"properties":{"asset_ids":{"items":{"type":"string"},"type":"array","title":"Asset Ids"},"container":{"type":"string","title":"Container","default":"mp4"}},"type":"object","required":["asset_ids"],"title":"_ConcatBody"},"_DomainBody":{"properties":{"domain":{"type":"string","title":"Domain"}},"type":"object","required":["domain"],"title":"_DomainBody"},"_DubBody":{"properties":{"subtitle_asset_id":{"type":"string","title":"Subtitle Asset Id"},"target_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Lang"},"keep_original":{"type":"boolean","title":"Keep Original","default":false}},"type":"object","required":["subtitle_asset_id"],"title":"_DubBody"},"_ImpersonateBody":{"properties":{"reason":{"type":"string","title":"Reason","default":""}},"type":"object","title":"_ImpersonateBody"},"_InviteBody":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"member"}},"type":"object","required":["email"],"title":"_InviteBody"},"_KeyBody":{"properties":{"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes","default":["read","jobs:create"]}},"type":"object","required":["name"],"title":"_KeyBody"},"_LoudnormBody":{"properties":{"target_lufs":{"type":"number","title":"Target Lufs","default":-14.0},"container":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Container"}},"type":"object","title":"_LoudnormBody"},"_MagicStart":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"_MagicStart"},"_MagicVerify":{"properties":{"email":{"type":"string","title":"Email"},"code":{"type":"string","title":"Code"}},"type":"object","required":["email","code"],"title":"_MagicVerify"},"_MarkerIn":{"properties":{"start_ms":{"type":"integer","minimum":0.0,"title":"Start Ms"},"title":{"type":"string","maxLength":200,"minLength":1,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["start_ms","title"],"title":"_MarkerIn"},"_MoveBody":{"properties":{"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","title":"_MoveBody"},"_OperatorBody":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["email","role"],"title":"_OperatorBody"},"_OverrideBody":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Value"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["key"],"title":"_OverrideBody"},"_PatchAssetBody":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"project_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Id"}},"type":"object","title":"_PatchAssetBody","description":"Partial update. Only fields actually sent are applied (we inspect\n`model_fields_set`), so `project_id: null` explicitly moves to uncategorised while an\nomitted `project_id` leaves the folder unchanged."},"_PublicTranscribeBody":{"properties":{"asset_id":{"type":"string","title":"Asset Id"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"}},"type":"object","required":["asset_id"],"title":"_PublicTranscribeBody"},"_PublishBody":{"properties":{"caption":{"type":"string","title":"Caption","default":""}},"type":"object","title":"_PublishBody"},"_QCBody":{"properties":{"reference_asset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reference Asset Id"},"target_lufs":{"type":"number","title":"Target Lufs","default":-14.0}},"type":"object","title":"_QCBody"},"_RemuxBody":{"properties":{"container":{"type":"string","title":"Container","default":"mp4"}},"type":"object","title":"_RemuxBody"},"_RenameBody":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"_RenameBody"},"_RoleBody":{"properties":{"role":{"type":"string","title":"Role"}},"type":"object","required":["role"],"title":"_RoleBody"},"_RouteBody":{"properties":{"kind":{"type":"string","title":"Kind"},"target_codec":{"type":"string","title":"Target Codec","default":"h264"},"source_codec":{"type":"string","title":"Source Codec","default":"h264"},"op":{"type":"string","title":"Op","default":"encode"},"width":{"type":"integer","title":"Width","default":1920},"height":{"type":"integer","title":"Height","default":1080},"duration_ms":{"type":"integer","title":"Duration Ms","default":0},"bit_depth":{"type":"integer","title":"Bit Depth","default":8},"is_deliverable":{"type":"boolean","title":"Is Deliverable","default":false},"is_batch":{"type":"boolean","title":"Is Batch","default":false},"hdr":{"type":"boolean","title":"Hdr","default":false},"dolby_vision":{"type":"boolean","title":"Dolby Vision","default":false},"hdr10_plus":{"type":"boolean","title":"Hdr10 Plus","default":false},"client_caps":{"anyOf":[{"$ref":"#/components/schemas/_RouteCaps"},{"type":"null"}]}},"type":"object","required":["kind"],"title":"_RouteBody","description":"A media op + the caller's client capabilities. The server returns the AUTHORITATIVE plan\n(the client mirrors the same logic but the server's verdict wins)."},"_RouteCaps":{"properties":{"hw_h264":{"type":"boolean","title":"Hw H264","default":false},"hw_vp9":{"type":"boolean","title":"Hw Vp9","default":false},"hw_av1":{"type":"boolean","title":"Hw Av1","default":false},"hw_av1_10bit":{"type":"boolean","title":"Hw Av1 10Bit","default":false},"hw_hevc":{"type":"boolean","title":"Hw Hevc","default":false},"webgpu":{"type":"boolean","title":"Webgpu","default":false},"max_pixels":{"type":"integer","title":"Max Pixels","default":2073600}},"type":"object","title":"_RouteCaps","description":"The browser's probed WebCodecs/WebGPU capabilities (advisory; None ⇒ headless)."},"_SaveChaptersBody":{"properties":{"markers":{"items":{"$ref":"#/components/schemas/_MarkerIn"},"type":"array","title":"Markers"}},"type":"object","required":["markers"],"title":"_SaveChaptersBody"},"_ScheduleBody":{"properties":{"platforms":{"items":{"type":"string"},"type":"array","title":"Platforms"},"caption":{"type":"string","title":"Caption","default":""},"when":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"When"}},"type":"object","required":["platforms"],"title":"_ScheduleBody"},"_SetPlanBody":{"properties":{"tier":{"type":"string","title":"Tier"}},"type":"object","required":["tier"],"title":"_SetPlanBody"},"_SettingBody":{"properties":{"key":{"type":"string","title":"Key"},"value":{"anyOf":[{"type":"string"},{"type":"boolean"}],"title":"Value"}},"type":"object","required":["key","value"],"title":"_SettingBody"},"_StorageBody":{"properties":{"backend":{"type":"string","title":"Backend"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["backend"],"title":"_StorageBody"},"_SubtitleBody":{"properties":{"raw":{"type":"string","title":"Raw"}},"type":"object","required":["raw"],"title":"_SubtitleBody"},"_SuspendBody":{"properties":{"suspended":{"type":"boolean","title":"Suspended"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["suspended"],"title":"_SuspendBody"},"_TierBody":{"properties":{"tier":{"type":"string","title":"Tier"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["tier"],"title":"_TierBody"},"_TokenBody":{"properties":{"name":{"type":"string","title":"Name","default":"scim"}},"type":"object","title":"_TokenBody"},"_TranscodeBody":{"properties":{"preset":{"type":"string","title":"Preset"},"container":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Container"}},"type":"object","required":["preset"],"title":"_TranscodeBody"},"_TranslateBody":{"properties":{"target_lang":{"type":"string","title":"Target Lang"},"source_lang":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Lang"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"}},"type":"object","required":["target_lang"],"title":"_TranslateBody"},"_TrimBody":{"properties":{"start_s":{"type":"number","title":"Start S"},"end_s":{"type":"number","title":"End S"},"container":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Container"},"precise":{"type":"boolean","title":"Precise","default":false}},"type":"object","required":["start_s","end_s"],"title":"_TrimBody"},"_UserSuspendBody":{"properties":{"suspended":{"type":"boolean","title":"Suspended"},"reason":{"type":"string","title":"Reason","default":""}},"type":"object","required":["suspended"],"title":"_UserSuspendBody"},"_WebhookBody":{"properties":{"url":{"type":"string","title":"Url"},"events":{"items":{"type":"string"},"type":"array","title":"Events","default":["*"]}},"type":"object","required":["url"],"title":"_WebhookBody"},"app__modules__projects__router___CreateBody":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"}},"type":"object","required":["name"],"title":"_CreateBody"},"app__modules__review__router___CreateBody":{"properties":{"asset_id":{"type":"string","title":"Asset Id"},"title":{"type":"string","title":"Title"},"assignee":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee"}},"type":"object","required":["asset_id","title"],"title":"_CreateBody"}}}}