{"openapi":"3.1.0","info":{"title":"Framewise HITL Dashboard API","version":"0.1.0"},"paths":{"/v1/klarity/avs":{"post":{"summary":"Post Klarity Avs Webhook","description":"Customer AVS ingestion scaffold.\n\nContract is intentionally narrow until Klarity confirms the final payload:\nsource URI must already be readable by the worker storage layer (`file://`\nlocally or `s3://` in cloud). Customer-hosted HTTPS signed URL fetch can be\nadded once their auth model is known.","operationId":"post_klarity_avs_webhook_v1_klarity_avs_post","responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Post Klarity Avs Webhook V1 Klarity Avs Post"}}}}}}},"/api/videos":{"get":{"summary":"Get Videos","description":"List in-flight videos with their current pending gate.\n\nworkflow_id is read directly off the videos row (persisted by parse_avs).\npending_gate is queried live from Temporal per-video — needs the workflow\nhandle, but no list scan.","operationId":"get_videos_api_videos_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Videos Api Videos Get"}}}}}}},"/api/admin/overview":{"get":{"summary":"Get Admin Overview","description":"Recent operational state across all videos.\n\nThis is the generic pilot dashboard endpoint. It intentionally avoids\nreturning full callback URLs or signed delivery URLs; operators can inspect\nper-video detail when they need deeper context.","operationId":"get_admin_overview_api_admin_overview_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":75,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Admin Overview Api Admin Overview Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/videos/{video_id}":{"get":{"summary":"Get Video Detail","description":"Full state for a single video — script segments + scenes + clip statuses.\nThe UI uses this to render the gate-specific review screen.","operationId":"get_video_detail_api_videos__video_id__get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Video Detail Api Videos  Video Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/videos/{video_id}/workflow":{"get":{"summary":"Get Workflow For Video","description":"Find the running Temporal workflow associated with this video.\nIncludes the currently-pending activity name (if any) so the UI can show\n'workflow is in render_clips, ~8 min' instead of an ambiguous null gate.","operationId":"get_workflow_for_video_api_videos__video_id__workflow_get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Workflow For Video Api Videos  Video Id  Workflow Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/videos/{video_id}/gates/{gate}":{"post":{"summary":"Post Gate Decision","description":"Signal a gate decision to the running workflow.\n\nAlso persists into review_events so we have an audit trail independent of\nTemporal's event history (which gets archived after 90 days by default).","operationId":"post_gate_decision_api_videos__video_id__gates__gate__post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}},{"name":"gate","in":"path","required":true,"schema":{"type":"string","title":"Gate"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GateActionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Gate Decision Api Videos  Video Id  Gates  Gate  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/videos/{video_id}/provider-review-links":{"post":{"summary":"Create Provider Review Link","description":"Create a scoped provider review link for one video.\n\nThe raw token is returned once. Only its SHA-256 hash is stored in Postgres.","operationId":"create_provider_review_link_api_videos__video_id__provider_review_links_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReviewLinkRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Provider Review Link Api Videos  Video Id  Provider Review Links Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/provider/reviews/{token}":{"get":{"summary":"Get Provider Review","operationId":"get_provider_review_api_provider_reviews__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Provider Review Api Provider Reviews  Token  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/provider/reviews/{token}/segments/{segment_id}":{"patch":{"summary":"Patch Provider Review Segment","operationId":"patch_provider_review_segment_api_provider_reviews__token__segments__segment_id__patch","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"segment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Segment Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReviewSegmentPatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Patch Provider Review Segment Api Provider Reviews  Token  Segments  Segment Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/provider/reviews/{token}/regenerate":{"post":{"summary":"Post Provider Review Regenerate","operationId":"post_provider_review_regenerate_api_provider_reviews__token__regenerate_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReviewRegenerateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Provider Review Regenerate Api Provider Reviews  Token  Regenerate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/provider/reviews/{token}/decision":{"post":{"summary":"Post Provider Review Decision","operationId":"post_provider_review_decision_api_provider_reviews__token__decision_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderReviewDecisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Provider Review Decision Api Provider Reviews  Token  Decision Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/provider/reviews/{token}":{"get":{"summary":"Provider Review Page","operationId":"provider_review_page_provider_reviews__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/script_segments/{segment_id}":{"patch":{"summary":"Patch Script Segment","description":"Edit a script segment at gate 1. If text changes, re-runs the PHI\nclassifier (regex + Claude) on this one segment and updates phi_flag +\nphi_identifiers from the result. Returns the post-update row plus a\nwarnings array (wps cap, duration minimum, PHI/heygen conflict).\nWarnings are advisory — never block the save.","operationId":"patch_script_segment_api_script_segments__segment_id__patch","parameters":[{"name":"segment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Segment Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScriptSegmentPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Patch Script Segment Api Script Segments  Segment Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/videos/{video_id}/chat":{"get":{"summary":"Get Chat","description":"Return persisted chat history for the video. Used by the UI on load\n+ after each turn to render the thread.","operationId":"get_chat_api_videos__video_id__chat_get","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Chat Api Videos  Video Id  Chat Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Post Chat","description":"Run one agent turn. The agent may fire multiple internal tool calls\n(list_scenes → reroll_scenes confirmation flow). Returns the final\nuser-facing text + list of actions taken.","operationId":"post_chat_api_videos__video_id__chat_post","parameters":[{"name":"video_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Video Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Post Chat Api Videos  Video Id  Chat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/health":{"get":{"summary":"Health","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Api Health Get"}}}}}}},"/api/logs":{"get":{"summary":"Get Logs","description":"Return the last N lines from the central log file, optionally\nsubstring-filtered. Useful for debugging without ssh'ing to the host.","operationId":"get_logs_api_logs_get","parameters":[{"name":"tail","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Tail"}},{"name":"grep","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grep"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Logs Api Logs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/artifact":{"get":{"summary":"Get Artifact","description":"Serve an S3-backed artifact URI.\n\nLocal artifacts are exposed through fixed `/artifacts/<root>/...` StaticFiles\nmounts generated by `_artifact_api_url`, so this endpoint never accepts a\ncaller-supplied filesystem path.","operationId":"get_artifact_api_artifact_get","parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ChatMessageRequest":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"ChatMessageRequest"},"GateActionRequest":{"properties":{"action":{"type":"string","title":"Action"},"reviewer_id":{"type":"string","title":"Reviewer Id","default":"ui"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"payload":{"additionalProperties":true,"type":"object","title":"Payload","default":{}}},"type":"object","required":["action"],"title":"GateActionRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ProviderReviewDecisionRequest":{"properties":{"action":{"type":"string","title":"Action"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"reviewer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Name"}},"type":"object","required":["action"],"title":"ProviderReviewDecisionRequest"},"ProviderReviewLinkRequest":{"properties":{"reviewer_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Email"},"reviewer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Name"},"expires_in_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Hours"},"created_by":{"type":"string","title":"Created By","default":"ui"}},"type":"object","title":"ProviderReviewLinkRequest"},"ProviderReviewRegenerateRequest":{"properties":{"attestation_accepted":{"type":"boolean","title":"Attestation Accepted","default":false},"attestation_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attestation Text"},"reviewer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Name"}},"type":"object","title":"ProviderReviewRegenerateRequest"},"ProviderReviewSegmentPatchRequest":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"removed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Removed"},"visual_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visual Mode"},"reviewer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Name"}},"type":"object","title":"ProviderReviewSegmentPatchRequest"},"ScriptSegmentPatch":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"target_audio_sec":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Target Audio Sec"},"delivery":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery"},"phi_flag":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Phi Flag"}},"type":"object","title":"ScriptSegmentPatch"},"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"}}}}