{"openapi":"3.1.0","info":{"title":"Kontext Video API","version":"0.1.0","description":"Analyze long-form video and serve ads over it: upload a video, read its time-aware analysis, and fetch the ad slots to render."},"servers":[{"url":"https://eiger.develop.kontext.ai"}],"security":[{"bearerAuth":[]}],"paths":{"/v1/ads":{"post":{"summary":"Request ad placements","operationId":"getAds","tags":["Ads"],"description":"Returns the overlay placements for a video, identified by `title_id`. Each placement carries a stable `iframe_url` to embed at its time slot. An empty `slots` array means there are no overlays for this playback.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdsRequest"}}}},"responses":{"200":{"description":"Ad slots to render over the video timeline (empty slots = no overlays)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationError"}}}},"/overlay/{slotId}":{"get":{"summary":"Render a creative overlay","operationId":"getOverlay","tags":["Ads"],"security":[],"description":"Renders the ad creative for a placement as an HTML document, designed to be embedded as a cross-origin `<iframe>` over the video player.\n\nWhen the viewer clicks the call-to-action, the creative sends a message to the parent window so the player can open the destination and coordinate playback (for example, pausing the video):\n\n```json\n{ \"type\": \"kontext.ad.click\", \"version\": 1, \"slot_id\": \"demo-123-0\", \"cta_url\": \"https://example.com/landing\" }\n```\n\nReacting to the click is the integrating player's responsibility: it must listen for this message, validate `event.origin` against this host, then open `cta_url` (it may also pause and resume playback). Without a listener the call-to-action is inert.","parameters":[{"name":"slotId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The ad creative.","content":{"text/html":{"schema":{"type":"string"}}}},"404":{"description":"No creative is available for this placement; empty body, so the iframe renders nothing."}}}},"/v1/upload":{"post":{"tags":["Titles"],"summary":"Upload","description":"Queue analysis of a video by URL (with an optional subtitle URL).","operationId":"upload_upload_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/titles/{title_id}":{"get":{"tags":["Titles"],"summary":"Get Title","description":"Read a title: a lean status while pending/failed, the full result once ready.","operationId":"get_title_titles__title_id__get","parameters":[{"name":"title_id","in":"path","required":true,"schema":{"type":"string","title":"Title Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/TitleStatus"},{"$ref":"#/components/schemas/TitleResult"}],"title":"Response Get Title Titles  Title Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AdsRequest":{"type":"object","required":["title_id"],"properties":{"title_id":{"type":"string","description":"Title id returned by the video-analysis POST /v1/upload"},"context":{"type":"object","properties":{"player_width":{"type":"integer"},"player_height":{"type":"integer"}}}}},"AdSlot":{"type":"object","required":["slot_id","start_ms","end_ms","placement","iframe_url","width","height","position"],"properties":{"slot_id":{"type":"string","example":"demo-123-0"},"start_ms":{"type":"integer","description":"Slot start offset in the video, milliseconds","example":47200},"end_ms":{"type":"integer","description":"Slot end offset in the video, milliseconds","example":57200},"placement":{"type":"string","enum":["overlay"],"example":"overlay"},"iframe_url":{"type":"string","format":"uri","description":"Embed as a cross-origin iframe over the player — a /overlay/{slotId} URL on this host","example":"https://example.com/overlay/demo-123-0"},"width":{"type":"integer","example":640},"height":{"type":"integer","example":100},"position":{"type":"string","enum":["top","bottom"],"description":"Overlay position (top/bottom edge of the video), from video analysis","example":"bottom"}}},"AdsResponse":{"type":"object","required":["title_id","slots"],"properties":{"title_id":{"type":"string","example":"demo-123"},"slots":{"type":"array","items":{"$ref":"#/components/schemas/AdSlot"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_json","invalid_request","unauthorized"]},"message":{"type":"string"}}}}},"BrandSafetyFinding":{"properties":{"category":{"$ref":"#/components/schemas/GarmCategoryLabel","description":"GARM brand-safety category present."},"tier":{"$ref":"#/components/schemas/GarmTier","description":"Severity tier (treatment x context)."},"certainty":{"$ref":"#/components/schemas/Certainty","description":"'clear' if unambiguous, else 'borderline'."},"evidence":{"type":"string","title":"Evidence","description":"Auditable support: a spoken quote or concrete visible content."}},"type":"object","required":["category","tier","certainty","evidence"],"title":"BrandSafetyFinding","description":"One GARM brand-safety category found in a scene, with evidence."},"BrandSafetyRollup":{"properties":{"scene_count":{"type":"integer","title":"Scene Count","description":"Total scenes in the title."},"safe_scenes":{"type":"integer","title":"Safe Scenes"},"unsafe_scenes":{"type":"integer","title":"Unsafe Scenes"},"safe_runtime_ms":{"type":"integer","title":"Safe Runtime Ms","description":"Brand-safe screen-time, in ms."},"rated_runtime_ms":{"type":"integer","title":"Rated Runtime Ms","description":"Screen-time that has a brand-safety rating, in ms."},"safety_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Safety Pct","description":"Screen-time-weighted brand-safe share, 0-100; null if unrated."},"tier_counts":{"items":{"$ref":"#/components/schemas/TierCount"},"type":"array","title":"Tier Counts","description":"Unsafe scenes by worst tier, largest screen-time first."},"categories":{"items":{"$ref":"#/components/schemas/CategoryCount"},"type":"array","title":"Categories","description":"All GARM categories summarized; flagged ones first."}},"type":"object","required":["scene_count","safe_scenes","unsafe_scenes","safe_runtime_ms","rated_runtime_ms","safety_pct"],"title":"BrandSafetyRollup","description":"Title-level brand-safety (GARM) summary across the title's scenes."},"CategoryCount":{"properties":{"category":{"$ref":"#/components/schemas/GarmCategoryLabel"},"scene_count":{"type":"integer","title":"Scene Count","description":"Scenes flagging this category (0 = clear)."},"runtime_ms":{"type":"integer","title":"Runtime Ms","description":"Screen-time of the flagging scenes, in ms."},"worst_tier":{"anyOf":[{"$ref":"#/components/schemas/GarmTier"},{"type":"null"}],"description":"Worst tier across flagging scenes; null when never flagged."}},"type":"object","required":["category","scene_count","runtime_ms","worst_tier"],"title":"CategoryCount","description":"One GARM category summarized across the title (per-scene detail is in `scenes`)."},"Certainty":{"type":"string","enum":["clear","borderline"],"title":"Certainty","description":"Confidence in a label: 'clear' is unambiguous, 'borderline' is uncertain."},"DialogueLine":{"properties":{"speaker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Speaker","description":"Speaker label, if known."},"quote":{"type":"string","title":"Quote","description":"Verbatim subtitle text."},"t_ms":{"type":"integer","title":"T Ms","description":"Absolute start time of the line on the title timeline, in ms."}},"type":"object","required":["quote","t_ms"],"title":"DialogueLine","description":"One subtitle line spoken during a scene."},"Emotion":{"properties":{"label":{"type":"string","title":"Label","description":"Emotion label."},"runtime_ms":{"type":"integer","title":"Runtime Ms","description":"On-screen time carrying this emotion, in ms."}},"type":"object","required":["label","runtime_ms"],"title":"Emotion","description":"One dominant emotion of the title, ranked by on-screen time."},"Entity":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Proper name if shown/spoken, else null."},"type":{"$ref":"#/components/schemas/EntityType","description":"Coarse entity kind."},"description":{"type":"string","title":"Description","description":"What it is and any salient attributes."}},"type":"object","required":["type","description"],"title":"Entity","description":"A person/object/brand/etc. present in a scene."},"EntityType":{"type":"string","enum":["person","group","animal","vehicle","product","brand","organization","object","place","text","other"],"title":"EntityType","description":"Kind of on-screen entity."},"Environment":{"type":"string","enum":["indoor","outdoor","other"],"title":"Environment","description":"Whether the scene is set indoors or outdoors."},"GarmCategoryLabel":{"type":"string","enum":["Adult & Explicit Sexual Content","Arms & Ammunition","Crime & Harmful Acts to Individuals and Society, Human Right Violations","Death, Injury or Military Conflict","Online Piracy","Hate Speech & Acts of Aggression","Obscenity and Profanity","Illegal Drugs / Tobacco / e-cigarettes / Vaping / Alcohol","Spam or Harmful Content","Terrorism","Debated Sensitive Social Issue","Misinformation"],"title":"GarmCategoryLabel","description":"Brand-safety category, per the GARM framework."},"GarmTier":{"type":"string","enum":["floor","low_risk","medium_risk","high_risk"],"title":"GarmTier","description":"Brand-safety risk tier (GARM): 'floor', then low / medium / high suitability risk."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IabGroup":{"properties":{"name":{"type":"string","title":"Name","description":"Tier-1 taxonomy segment."},"sensitive":{"type":"boolean","title":"Sensitive","description":"Whether this whole segment is brand-sensitive."},"coverage_ms":{"type":"integer","title":"Coverage Ms","description":"Screen-time touching any topic in the group."},"topics":{"items":{"$ref":"#/components/schemas/IabTopic"},"type":"array","title":"Topics"}},"type":"object","required":["name","sensitive","coverage_ms"],"title":"IabGroup","description":"A tier-1 taxonomy segment and the topics grouped under it."},"IabRollup":{"properties":{"groups":{"items":{"$ref":"#/components/schemas/IabGroup"},"type":"array","title":"Groups","description":"Tier-1 groups, largest coverage first."},"topic_count":{"type":"integer","title":"Topic Count","description":"Distinct topics across the title."},"tagged_scenes":{"type":"integer","title":"Tagged Scenes","description":"Scenes carrying at least one topic."},"total_scenes":{"type":"integer","title":"Total Scenes","description":"Total scenes considered."}},"type":"object","required":["topic_count","tagged_scenes","total_scenes"],"title":"IabRollup","description":"Title-level IAB topic coverage, grouped by tier-1 segment."},"IabTopic":{"properties":{"id":{"type":"string","title":"Id","description":"IAB Content Taxonomy id."},"name":{"type":"string","title":"Name","description":"Topic name."},"path":{"type":"string","title":"Path","description":"Full ' > '-delimited taxonomy path."},"group":{"type":"string","title":"Group","description":"Tier-1 taxonomy segment the topic groups under."},"sensitive":{"type":"boolean","title":"Sensitive","description":"Brand-sensitive topic (sensitive branch)."},"scene_count":{"type":"integer","title":"Scene Count","description":"Scenes carrying this topic."},"coverage_ms":{"type":"integer","title":"Coverage Ms","description":"Screen-time of those scenes, in ms."},"certainty":{"$ref":"#/components/schemas/Certainty","description":"'clear' if confidently present in at least one scene, else 'borderline'."}},"type":"object","required":["id","name","path","group","sensitive","scene_count","coverage_ms","certainty"],"title":"IabTopic","description":"One IAB topic summarized across the title (per-scene detail is in `scenes`)."},"Scene":{"properties":{"scene_index":{"type":"integer","title":"Scene Index","description":"0-based scene index on the title timeline."},"start_ms":{"type":"integer","title":"Start Ms","description":"Scene start on the title timeline, in ms."},"end_ms":{"type":"integer","title":"End Ms","description":"Scene end on the title timeline, in ms."},"label":{"type":"string","title":"Label","description":"Short scene label."},"description":{"type":"string","title":"Description","description":"What happens in the scene."},"setting":{"anyOf":[{"$ref":"#/components/schemas/Setting"},{"type":"null"}]},"entities":{"items":{"$ref":"#/components/schemas/Entity"},"type":"array","title":"Entities"},"dialogue":{"items":{"$ref":"#/components/schemas/DialogueLine"},"type":"array","title":"Dialogue","description":"Subtitle lines spoken during the scene."},"topics":{"items":{"type":"string"},"type":"array","title":"Topics","description":"Free-text topic keywords for the scene."},"mood":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mood","description":"Dominant mood, if discernible."},"safe":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Safe","description":"Whether the scene is brand-safe (GARM); null if not rated."},"brand_safety_findings":{"items":{"$ref":"#/components/schemas/BrandSafetyFinding"},"type":"array","title":"Brand Safety Findings","description":"GARM findings for the scene (empty if safe)."},"iab_topics":{"items":{"$ref":"#/components/schemas/TopicLabel"},"type":"array","title":"Iab Topics","description":"IAB taxonomy topics detected in the scene."}},"type":"object","required":["scene_index","start_ms","end_ms","label","description"],"title":"Scene","description":"One scene of the title with its description and per-scene classifications."},"Sentiment":{"type":"string","enum":["positive","neutral","negative","mixed"],"title":"Sentiment","description":"Overall emotional lean of the title."},"Setting":{"properties":{"place":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Place","description":"Free-text location, e.g. 'city street'."},"time_of_day":{"anyOf":[{"$ref":"#/components/schemas/TimeOfDay"},{"type":"null"}],"description":"Time of day if discernible."},"environment":{"anyOf":[{"$ref":"#/components/schemas/Environment"},{"type":"null"}],"description":"Indoor/outdoor if discernible."}},"type":"object","title":"Setting","description":"Where a scene takes place."},"Synopsis":{"properties":{"logline":{"type":"string","title":"Logline","description":"One-sentence capture of the whole title."},"synopsis":{"type":"string","title":"Synopsis","description":"2-4 sentence summary of the title."},"themes":{"items":{"type":"string"},"type":"array","title":"Themes","description":"Recurring subjects/themes as keywords."},"sentiment":{"$ref":"#/components/schemas/Sentiment","description":"Overall affective lean of the title."},"emotions":{"items":{"$ref":"#/components/schemas/Emotion"},"type":"array","title":"Emotions","description":"Dominant emotions, strongest (most screen-time) first."}},"type":"object","required":["logline","synopsis","sentiment"],"title":"Synopsis","description":"Whole-title overview: a written synopsis plus an emotion breakdown."},"TierCount":{"properties":{"tier":{"$ref":"#/components/schemas/GarmTier"},"scene_count":{"type":"integer","title":"Scene Count","description":"Scenes whose worst tier is this tier."},"runtime_ms":{"type":"integer","title":"Runtime Ms","description":"Screen-time of those scenes, in ms."}},"type":"object","required":["tier","scene_count","runtime_ms"],"title":"TierCount","description":"Unsafe scenes sharing one worst-case GARM tier: their count + screen-time."},"TimeOfDay":{"type":"string","enum":["dawn","day","dusk","night","other"],"title":"TimeOfDay","description":"Time of day depicted in the scene."},"TitleResult":{"properties":{"title_id":{"type":"string","title":"Title Id","description":"Opaque title id (the value from upload)."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Display title."},"status":{"type":"string","enum":["processing","ready","failed"],"title":"Status","description":"Always 'ready' for this full response; pending/failed titles return TitleStatus."},"duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Ms","description":"Title duration in ms, if known."},"synopsis":{"anyOf":[{"$ref":"#/components/schemas/Synopsis"},{"type":"null"}],"description":"Whole-title overview; null until ready."},"brand_safety":{"anyOf":[{"$ref":"#/components/schemas/BrandSafetyRollup"},{"type":"null"}],"description":"Title-level brand-safety (GARM) rollup."},"iab":{"anyOf":[{"$ref":"#/components/schemas/IabRollup"},{"type":"null"}],"description":"Title-level IAB topic coverage rollup."},"scenes":{"items":{"$ref":"#/components/schemas/Scene"},"type":"array","title":"Scenes"}},"type":"object","required":["title_id","title","status","duration_ms"],"title":"TitleResult","description":"Everything we know about a title and its scenes — the ready `GET /v1/titles/{id}` body."},"TitleStatus":{"properties":{"title_id":{"type":"string","title":"Title Id","description":"Opaque title id (the value from upload)."},"status":{"type":"string","enum":["processing","ready","failed"],"title":"Status","description":"'processing' while analysis runs, or 'failed'. Poll until 'ready'."},"result_url":{"type":"string","title":"Result Url","description":"Path to poll for the full result, e.g. /v1/titles/<title_id>."}},"type":"object","required":["title_id","status","result_url"],"title":"TitleStatus","description":"Lean status envelope returned while a title is still processing or has failed.\n\nThe full analysis (synopsis, brand_safety, iab, scenes) is returned only once\n`status` is `ready` — see `TitleResult`."},"TopicLabel":{"properties":{"id":{"type":"string","title":"Id","description":"IAB Content Taxonomy id."},"name":{"type":"string","title":"Name","description":"Topic name."},"path":{"type":"string","title":"Path","description":"Full ' > '-delimited taxonomy path."},"evidence":{"type":"string","title":"Evidence","description":"Auditable support: a spoken quote or concrete visible content."},"certainty":{"$ref":"#/components/schemas/Certainty","description":"'clear' if plainly present, else 'borderline'."}},"type":"object","required":["id","name","path","evidence","certainty"],"title":"TopicLabel","description":"One IAB Content Taxonomy topic detected in a scene."},"UploadRequest":{"properties":{"video_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Video Url","description":"Public URL of the source video to analyze."},"subtitle_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Subtitle Url","description":"Optional URL of a subtitle (.srt) file. When omitted, the video's own subtitles are used when available."},"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title","description":"Optional display title; taken from the video filename when omitted."}},"type":"object","required":["video_url"],"title":"UploadRequest","description":"Request body for `POST /v1/upload`."},"UploadResponse":{"properties":{"title_id":{"type":"string","title":"Title Id","description":"Opaque id for the title; poll the result endpoint with it."},"status":{"type":"string","enum":["processing","ready","failed"],"title":"Status","description":"Lifecycle status; always 'processing' immediately after upload."},"result_url":{"type":"string","title":"Result Url","description":"Relative path to poll for the result, e.g. /v1/titles/<title_id>."}},"type":"object","required":["title_id","status","result_url"],"title":"UploadResponse","description":"Response for `POST /v1/upload` — analysis has been queued."},"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"}},"responses":{"BadRequest":{"description":"Malformed request (e.g. invalid JSON)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationError":{"description":"Request body failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}}}