{"openapi":"3.1.0","info":{"title":"CLIP API","version":"1.0.0","description":"Public catalogue API (no authentication) and studio API (session cookie, same-origin, role-based). Public responses never contain prompts or costs."},"servers":[{"url":"https://clip.spboucher.ai"}],"components":{"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"clip_session"}}},"paths":{"/api/films":{"get":{"summary":"Published films, newest first","parameters":[{"name":"locale","in":"query","schema":{"type":"string","enum":["en","fr"],"default":"en"}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":48,"default":12}},{"name":"series","in":"query","schema":{"type":"string"}},{"name":"tag","in":"query","schema":{"type":"string"}},{"name":"language","in":"query","schema":{"type":"string"}},{"name":"kind","in":"query","schema":{"type":"string"}},{"name":"maxDuration","in":"query","schema":{"type":"number"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["latest","top"]}}],"responses":{"200":{"description":"A page of films","content":{"application/json":{"schema":{"type":"object","properties":{"films":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"synopsis":{"type":"string"},"takeaway":{"type":"string"},"language":{"type":"string"},"kind":{"type":"string"},"duration":{"type":"number"},"video":{"type":"string"},"videoLow":{"type":"string"},"poster":{"type":"string"},"thumb":{"type":"string"},"publishedAt":{"type":"string"},"likes":{"type":"number"},"views":{"type":"number"}}}},"nextCursor":{"type":["string","null"]}}}}}}}}},"/api/films/{slug}":{"get":{"summary":"One film with provenance, sources and explained recommendations","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"locale","in":"query","schema":{"type":"string","enum":["en","fr"],"default":"en"}}],"responses":{"200":{"description":"Film","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Unknown or withdrawn film"}}}},"/api/films/{slug}/react":{"post":{"summary":"Anonymous like / unlike","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"like":{"type":"boolean"}},"required":["like"]}}}},"responses":{"200":{"description":"New like count","content":{"application/json":{"schema":{"type":"object","properties":{"likes":{"type":"number"}}}}}}}}},"/api/series":{"get":{"summary":"Editorial series","parameters":[{"name":"locale","in":"query","schema":{"type":"string","enum":["en","fr"],"default":"en"}}],"responses":{"200":{"description":"Series","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/search":{"get":{"summary":"Explainable hybrid search","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"locale","in":"query","schema":{"type":"string","enum":["en","fr"],"default":"en"}}],"responses":{"200":{"description":"Results with the signals that matched","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/events":{"post":{"summary":"Anonymous view / complete / share counter","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"filmId":{"type":"string"},"kind":{"type":"string","enum":["view","complete","share"]},"locale":{"type":"string"}},"required":["filmId","kind"]}}}},"responses":{"204":{"description":"Recorded"}}}},"/api/reports":{"post":{"summary":"Report a problem with a film","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"film":{"type":"string"},"reason":{"type":"string"},"detail":{"type":"string"},"contact":{"type":"string"}},"required":["detail"]}}}},"responses":{"201":{"description":"Filed","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/health":{"get":{"summary":"Dependency health","responses":{"200":{"description":"ok or degraded","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"down"}}}},"/api/studio/concepts":{"post":{"summary":"Create a project from a brief and queue four scored pitches","security":[{"session":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string"},"objective":{"type":"string"},"audience":{"type":"string"},"mood":{"type":"string"},"genre":{"type":"string"},"constraints":{"type":"string"},"language":{"type":"string","enum":["en","fr","bilingual"]},"seriesSlug":{"type":"string"},"shots":{"type":"integer","minimum":2,"maximum":6},"mode":{"type":"string","enum":["manual","assisted","autonomous"]},"quality":{"type":"string","enum":["draft","master"]}},"required":["theme"]}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string"},"duplicate":{"type":"boolean"}}}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/projects":{"get":{"summary":"Recent projects","security":[{"session":[]}],"responses":{"200":{"description":"Projects","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}},"post":{"summary":"Create a project from a single concept","security":[{"session":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"theme":{"type":"string"}},"required":["theme"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/projects/{id}/generate":{"post":{"summary":"Run a pipeline stage (or the next one)","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"stage":{"type":"string","enum":["concept","script","storyboard","keyframes","voice","video","assemble","qa"]},"fresh":{"type":"boolean"}},"required":[]}}}},"responses":{"202":{"description":"Queued; repeating the call returns the same job","content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string"},"stage":{"type":"string"},"duplicate":{"type":"boolean"}}}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/shots/{id}/regenerate":{"post":{"summary":"Regenerate the keyframe, clip or voice of one shot (capped)","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"what":{"type":"string","enum":["image","video","voice"]},"approve":{"type":"boolean"}},"required":["what"]}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/jobs/{id}":{"get":{"summary":"State of a stage run and its provider calls","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Job","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/films/{id}/approve":{"post":{"summary":"Approve the current cut (id = project id)","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"override":{"type":"boolean"},"note":{"type":"string"}},"required":[]}}}},"responses":{"200":{"description":"Approved","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/films/{id}/publish":{"post":{"summary":"Publish or schedule an approved cut (id = project id)","security":[{"session":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"scheduleFor":{"type":"string","format":"date-time"},"featured":{"type":"boolean"}},"required":[]}}}},"responses":{"200":{"description":"Published or scheduled","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/costs":{"get":{"summary":"Spend, ceilings, estimated vs actual","security":[{"session":[]}],"responses":{"200":{"description":"Costs","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}},"/api/studio/kill-switch":{"post":{"summary":"Stop or allow new paid jobs","security":[{"session":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"on":{"type":"boolean"}},"required":["on"]}}}},"responses":{"200":{"description":"State","content":{"application/json":{"schema":{"type":"object","properties":{"killSwitch":{"type":"boolean"},"inFlight":{"type":"number"}}}}}},"401":{"description":"Not signed in"},"403":{"description":"Role too low, or cross-origin request"},"409":{"description":"Not allowed in the current state (budget, kill switch, status)"},"429":{"description":"Rate limited"}}}}}}