{"openapi":"3.0.0","info":{"title":"Pythia","version":"0.1.0","description":"The API behind the five areas."},"components":{"schemas":{},"parameters":{}},"paths":{"/api/health":{"get":{"summary":"Is the app up, and does the database answer","description":"Role: public.","tags":["ops"],"responses":{"200":{"description":"Up","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}},"503":{"description":"The database does not answer","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]}}}}}}},"/api/auth/login":{"post":{"summary":"Log in as the admin with the environment's password","description":"Role: public.","tags":["auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":1,"maxLength":500}},"required":["password"],"additionalProperties":false}}}},"responses":{"200":{"description":"Logged in; the session cookie is set","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin"]}},"required":["role"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Wrong password","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"429":{"description":"Too many tries","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"No admin password is configured","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/auth/logout":{"post":{"summary":"End the admin's session and clear the cookie","description":"Role: public.","tags":["auth"],"responses":{"204":{"description":"Logged out (also when there was nothing to end)"}}}},"/api/auth/me":{"get":{"summary":"Is this browser logged in as the admin","description":"Role: admin.","tags":["auth"],"responses":{"200":{"description":"The admin","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin"]}},"required":["role"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tags":{"get":{"summary":"List tags","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"dimension","in":"query"},{"schema":{"type":"string"},"required":false,"name":"parent_slug","in":"query"},{"schema":{"type":"string"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of tags","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"returned":{"type":"integer"},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"dimension":{"type":"string","enum":["topic","tone","audience","setting","era_resonance","region_resonance"]},"description":{"type":"string","nullable":true},"parent_id":{"type":"string","nullable":true,"format":"uuid"},"aliases":{"type":"array","items":{"type":"string"}},"controlled":{"type":"boolean"},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","slug","name","dimension","description","parent_id","aliases","controlled","has_embedding","created_at"]}}},"required":["limit","offset","returned","tags"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Create a tag, after the near-duplicate check (D12)","description":"Role: admin.","tags":["content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"dimension":{"type":"string","enum":["topic","tone","audience","setting","era_resonance","region_resonance"]},"description":{"type":"string","maxLength":500},"parent_slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"aliases":{"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"force":{"type":"boolean"}},"required":["name","dimension"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new tag","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"dimension":{"type":"string","enum":["topic","tone","audience","setting","era_resonance","region_resonance"]},"description":{"type":"string","nullable":true},"parent_id":{"type":"string","nullable":true,"format":"uuid"},"aliases":{"type":"array","items":{"type":"string"}},"controlled":{"type":"boolean"},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","slug","name","dimension","description","parent_id","aliases","controlled","has_embedding","created_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"503":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tags/{id}":{"patch":{"summary":"Edit a tag","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","nullable":true,"maxLength":500},"aliases":{"type":"array","items":{"type":"string","minLength":1,"maxLength":80}},"parent_slug":{"type":"string","nullable":true,"pattern":"^[a-z0-9-]+$"},"controlled":{"type":"boolean"}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tag, edited","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"dimension":{"type":"string","enum":["topic","tone","audience","setting","era_resonance","region_resonance"]},"description":{"type":"string","nullable":true},"parent_id":{"type":"string","nullable":true,"format":"uuid"},"aliases":{"type":"array","items":{"type":"string"}},"controlled":{"type":"boolean"},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","slug","name","dimension","description","parent_id","aliases","controlled","has_embedding","created_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tags/{id}/merge":{"post":{"summary":"Merge a tag into another of its dimension","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target_slug":{"type":"string","pattern":"^[a-z0-9-]+$"}},"required":["target_slug"],"additionalProperties":false}}}},"responses":{"200":{"description":"The winning tag and how many questions moved","content":{"application/json":{"schema":{"type":"object","properties":{"target":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"dimension":{"type":"string","enum":["topic","tone","audience","setting","era_resonance","region_resonance"]},"description":{"type":"string","nullable":true},"parent_id":{"type":"string","nullable":true,"format":"uuid"},"aliases":{"type":"array","items":{"type":"string"}},"controlled":{"type":"boolean"},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"}},"required":["id","slug","name","dimension","description","parent_id","aliases","controlled","has_embedding","created_at"]},"questions_relinked":{"type":"integer"}},"required":["target","questions_relinked"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/tags/{id}/relationships":{"get":{"summary":"The relationships going out of a tag","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The relationships","content":{"application/json":{"schema":{"type":"object","properties":{"tag_id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"relationships":{"type":"array","items":{"type":"object","properties":{"source_tag_id":{"type":"string","format":"uuid"},"target_tag_id":{"type":"string","format":"uuid"},"target_slug":{"type":"string"},"target_name":{"type":"string"},"relationship":{"type":"string","enum":["see_also","implies","conflicts_with","narrower_than","broader_than","often_co_occurs"]},"confidence":{"type":"number"},"applied_by":{"type":"string"}},"required":["source_tag_id","target_tag_id","target_slug","target_name","relationship","confidence","applied_by"]}}},"required":["tag_id","slug","relationships"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Add (or re-weight) a relationship from a tag to another","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target_slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"relationship":{"type":"string","enum":["see_also","implies","conflicts_with","narrower_than","broader_than","often_co_occurs"]},"confidence":{"type":"number","minimum":0,"maximum":1}},"required":["target_slug","relationship"],"additionalProperties":false}}}},"responses":{"201":{"description":"The relationship","content":{"application/json":{"schema":{"type":"object","properties":{"source_id":{"type":"string","format":"uuid"},"source_slug":{"type":"string"},"target_id":{"type":"string","format":"uuid"},"target_slug":{"type":"string"},"relationship":{"type":"string","enum":["see_also","implies","conflicts_with","narrower_than","broader_than","often_co_occurs"]},"confidence":{"type":"number"},"applied_by":{"type":"string"},"created_at":{"type":"string"}},"required":["source_id","source_slug","target_id","target_slug","relationship","confidence","applied_by","created_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/questions":{"get":{"summary":"List questions, newest first","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"language","in":"query"},{"schema":{"type":"string"},"required":false,"name":"rendering_format","in":"query"},{"schema":{"type":"string"},"required":false,"name":"fact_id","in":"query"},{"schema":{"type":"string"},"required":false,"name":"question_type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"difficulty_min","in":"query"},{"schema":{"type":"string"},"required":false,"name":"difficulty_max","in":"query"},{"schema":{"type":"string"},"required":false,"name":"has_embedding","in":"query"},{"schema":{"type":"string"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of questions","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"returned":{"type":"integer"},"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","nullable":true},"prompt":{"type":"string"},"prompt_media":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"question_type":{"type":"string"},"answers":{"type":"object","additionalProperties":{"nullable":true}},"language":{"type":"string"},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"content_rating":{"type":"string","nullable":true},"content_version":{"type":"integer"},"fact_id":{"type":"string","nullable":true,"format":"uuid"},"rendering_format":{"type":"string","nullable":true},"author":{"type":"string","nullable":true},"licence":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","prompt","prompt_media","question_type","answers","language","difficulty","content_rating","content_version","fact_id","rendering_format","author","licence","metadata","has_embedding","created_at","updated_at"]}}},"required":["limit","offset","returned","questions"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Create a question as a rendering of a fact","description":"Role: admin.","tags":["content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000},"question_type":{"type":"string","minLength":1,"maxLength":64},"answers":{"type":"object","additionalProperties":{"nullable":true}},"fact_id":{"type":"string","format":"uuid"},"rendering_format":{"type":"string","pattern":"^[a-z][a-z0-9_]+$"},"language":{"type":"string"},"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"difficulty":{"type":"integer","minimum":1,"maximum":100},"content_rating":{"type":"string","maxLength":32},"prompt_media":{"type":"object","additionalProperties":{"nullable":true}},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"author":{"type":"string","maxLength":200},"licence":{"type":"string","maxLength":200}},"required":["prompt","question_type","answers","fact_id"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new question","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","nullable":true},"prompt":{"type":"string"},"prompt_media":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"question_type":{"type":"string"},"answers":{"type":"object","additionalProperties":{"nullable":true}},"language":{"type":"string"},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"content_rating":{"type":"string","nullable":true},"content_version":{"type":"integer"},"fact_id":{"type":"string","nullable":true,"format":"uuid"},"rendering_format":{"type":"string","nullable":true},"author":{"type":"string","nullable":true},"licence":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","prompt","prompt_media","question_type","answers","language","difficulty","content_rating","content_version","fact_id","rendering_format","author","licence","metadata","has_embedding","created_at","updated_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/questions/{id}":{"get":{"summary":"One question","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The question","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","nullable":true},"prompt":{"type":"string"},"prompt_media":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"question_type":{"type":"string"},"answers":{"type":"object","additionalProperties":{"nullable":true}},"language":{"type":"string"},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"content_rating":{"type":"string","nullable":true},"content_version":{"type":"integer"},"fact_id":{"type":"string","nullable":true,"format":"uuid"},"rendering_format":{"type":"string","nullable":true},"author":{"type":"string","nullable":true},"licence":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","prompt","prompt_media","question_type","answers","language","difficulty","content_rating","content_version","fact_id","rendering_format","author","licence","metadata","has_embedding","created_at","updated_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"patch":{"summary":"Edit a question; a semantic edit bumps content_version","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"maxLength":2000},"prompt_media":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"answers":{"type":"object","additionalProperties":{"nullable":true}},"question_type":{"type":"string","minLength":1,"maxLength":64},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"content_rating":{"type":"string","nullable":true,"maxLength":32},"author":{"type":"string","nullable":true,"maxLength":200},"licence":{"type":"string","nullable":true,"maxLength":200},"metadata":{"type":"object","additionalProperties":{"nullable":true}}},"additionalProperties":false}}}},"responses":{"200":{"description":"The question, edited","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","nullable":true},"prompt":{"type":"string"},"prompt_media":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"question_type":{"type":"string"},"answers":{"type":"object","additionalProperties":{"nullable":true}},"language":{"type":"string"},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"content_rating":{"type":"string","nullable":true},"content_version":{"type":"integer"},"fact_id":{"type":"string","nullable":true,"format":"uuid"},"rendering_format":{"type":"string","nullable":true},"author":{"type":"string","nullable":true},"licence":{"type":"string","nullable":true},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"has_embedding":{"type":"boolean"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","prompt","prompt_media","question_type","answers","language","difficulty","content_rating","content_version","fact_id","rendering_format","author","licence","metadata","has_embedding","created_at","updated_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"delete":{"summary":"Delete a question that no pack uses","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/packs":{"get":{"summary":"List packs, newest first","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"origin","in":"query"},{"schema":{"type":"string"},"required":false,"name":"published","in":"query"},{"schema":{"type":"string"},"required":false,"name":"verified","in":"query"},{"schema":{"type":"string"},"required":false,"name":"show","in":"query"},{"schema":{"type":"string"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of packs","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"returned":{"type":"integer"},"packs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cover_image_url":{"type":"string","nullable":true},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"published":{"type":"boolean"},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"question_count":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","name","description","cover_image_url","origin","published","verified","metadata","question_count","created_at","updated_at"]}}},"required":["limit","offset","returned","packs"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Create a pack and its ladder in one transaction","description":"Role: admin.","tags":["content"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[a-z0-9-]+$"},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","nullable":true,"maxLength":2000},"cover_image_url":{"type":"string","nullable":true,"maxLength":2000},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"language":{"type":"string"},"show":{"type":"string"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"fastest_finger":{"type":"string","nullable":true,"pattern":"^[a-z0-9-]+$"},"ladder":{"type":"array","items":{"type":"string","pattern":"^[a-z0-9-]+$"}}},"required":["slug","name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new pack, with its ladder","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cover_image_url":{"type":"string","nullable":true},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"published":{"type":"boolean"},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"question_count":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"ladder":{"type":"array","items":{"type":"object","properties":{"question_id":{"type":"string","format":"uuid"},"question_slug":{"type":"string","nullable":true},"position":{"type":"integer"}},"required":["question_id","question_slug","position"]}}},"required":["id","slug","name","description","cover_image_url","origin","published","verified","metadata","question_count","created_at","updated_at","ladder"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/packs/{id}":{"get":{"summary":"One pack, with its resolved ladder","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The pack","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cover_image_url":{"type":"string","nullable":true},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"published":{"type":"boolean"},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"question_count":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"ladder":{"type":"array","items":{"type":"object","properties":{"question_id":{"type":"string","format":"uuid"},"question_slug":{"type":"string","nullable":true},"position":{"type":"integer"}},"required":["question_id","question_slug","position"]}}},"required":["id","slug","name","description","cover_image_url","origin","published","verified","metadata","question_count","created_at","updated_at","ladder"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"patch":{"summary":"Edit a pack; a ladder replaces its membership wholesale","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","nullable":true,"maxLength":2000},"cover_image_url":{"type":"string","nullable":true,"maxLength":2000},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"fastest_finger":{"type":"string","nullable":true,"pattern":"^[a-z0-9-]+$"},"ladder":{"type":"array","items":{"type":"string","pattern":"^[a-z0-9-]+$"}}},"additionalProperties":false}}}},"responses":{"200":{"description":"The pack, edited","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cover_image_url":{"type":"string","nullable":true},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"published":{"type":"boolean"},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"question_count":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"ladder":{"type":"array","items":{"type":"object","properties":{"question_id":{"type":"string","format":"uuid"},"question_slug":{"type":"string","nullable":true},"position":{"type":"integer"}},"required":["question_id","question_slug","position"]}}},"required":["id","slug","name","description","cover_image_url","origin","published","verified","metadata","question_count","created_at","updated_at","ladder"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"delete":{"summary":"Delete a pack that no game uses","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/packs/{id}/publish":{"post":{"summary":"Publish or unpublish a pack","description":"Role: admin.","tags":["content"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"published":{"type":"boolean"}},"required":["published"],"additionalProperties":false}}}},"responses":{"200":{"description":"The pack","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"cover_image_url":{"type":"string","nullable":true},"origin":{"type":"string","enum":["curated","ephemeral","user_created","imported"]},"published":{"type":"boolean"},"verified":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":{"nullable":true}},"question_count":{"type":"integer"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","slug","name","description","cover_image_url","origin","published","verified","metadata","question_count","created_at","updated_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/retrieve/pack":{"post":{"summary":"Assemble a pack of questions for a show","description":"Role: admin.","tags":["retrieval"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"show":{"type":"string","pattern":"^[a-z][a-z0-9_]+$"},"count":{"type":"integer","minimum":1,"maximum":100},"language":{"type":"string"},"tags":{"type":"array","items":{"type":"string","pattern":"^[a-z0-9-]+$"}},"difficulty_min":{"type":"integer","minimum":1,"maximum":100},"difficulty_max":{"type":"integer","minimum":1,"maximum":100},"readiness":{"type":"string","enum":["strict","permissive"]},"order":{"type":"string","enum":["random","difficulty_asc","difficulty_desc"]}},"required":["show","count"],"additionalProperties":false}}}},"responses":{"200":{"description":"The questions that matched","content":{"application/json":{"schema":{"type":"object","properties":{"show":{"type":"string"},"rendering_format":{"type":"string"},"language":{"type":"string"},"count_requested":{"type":"integer"},"count_returned":{"type":"integer"},"readiness":{"type":"string","enum":["strict","permissive"]},"order":{"type":"string","enum":["random","difficulty_asc","difficulty_desc"]},"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","nullable":true},"prompt":{"type":"string"},"question_type":{"type":"string"},"answers":{"type":"object","additionalProperties":{"nullable":true}},"difficulty":{"type":"integer","nullable":true,"minimum":1,"maximum":100},"language":{"type":"string"},"fact_id":{"type":"string","nullable":true,"format":"uuid"},"rendering_format":{"type":"string","nullable":true},"tag_slugs":{"type":"array","items":{"type":"string"}}},"required":["id","slug","prompt","question_type","answers","difficulty","language","fact_id","rendering_format","tag_slugs"]}}},"required":["show","rendering_format","language","count_requested","count_returned","readiness","order","questions"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/forge/items":{"post":{"summary":"Submit raw input to the forge; the proposer picks it up from the jobs table","description":"Role: admin.","tags":["forge"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}}},"required":["input_kind","input_payload"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new item, at status submitted","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"string","enum":["submitted","awaiting_review","iterating","committed","rejected","abandoned"]},"proposed_fact":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"proposed_renderings":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"similar_fact_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"scores":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"iteration_count":{"type":"integer"},"submitted_by":{"type":"string","nullable":true},"reviewed_by":{"type":"string","nullable":true},"reviewer_feedback":{"type":"string","nullable":true},"committed_fact_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"reviewed_at":{"type":"string","nullable":true},"committed_at":{"type":"string","nullable":true}},"required":["id","input_kind","input_payload","status","proposed_fact","proposed_renderings","similar_fact_ids","scores","iteration_count","submitted_by","reviewed_by","reviewer_feedback","committed_fact_id","created_at","updated_at","reviewed_at","committed_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"get":{"summary":"Forge items, newest first; filter by status for the review queue","description":"Role: admin.","tags":["forge"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of items","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"string","enum":["submitted","awaiting_review","iterating","committed","rejected","abandoned"]},"proposed_fact":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"proposed_renderings":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"similar_fact_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"scores":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"iteration_count":{"type":"integer"},"submitted_by":{"type":"string","nullable":true},"reviewed_by":{"type":"string","nullable":true},"reviewer_feedback":{"type":"string","nullable":true},"committed_fact_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"reviewed_at":{"type":"string","nullable":true},"committed_at":{"type":"string","nullable":true}},"required":["id","input_kind","input_payload","status","proposed_fact","proposed_renderings","similar_fact_ids","scores","iteration_count","submitted_by","reviewed_by","reviewer_feedback","committed_fact_id","created_at","updated_at","reviewed_at","committed_at"]}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["items","limit","offset"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/forge/items/{id}":{"get":{"summary":"One forge item, with its proposal, scores and review state","description":"Role: admin.","tags":["forge"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The item","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"string","enum":["submitted","awaiting_review","iterating","committed","rejected","abandoned"]},"proposed_fact":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"proposed_renderings":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"similar_fact_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"scores":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"iteration_count":{"type":"integer"},"submitted_by":{"type":"string","nullable":true},"reviewed_by":{"type":"string","nullable":true},"reviewer_feedback":{"type":"string","nullable":true},"committed_fact_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"reviewed_at":{"type":"string","nullable":true},"committed_at":{"type":"string","nullable":true}},"required":["id","input_kind","input_payload","status","proposed_fact","proposed_renderings","similar_fact_ids","scores","iteration_count","submitted_by","reviewed_by","reviewer_feedback","committed_fact_id","created_at","updated_at","reviewed_at","committed_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/forge/items/{id}/abandon":{"post":{"summary":"Give up on an item. Send {} when there is no reason","description":"Role: admin.","tags":["forge"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}},"additionalProperties":false}}}},"responses":{"200":{"description":"The item, abandoned","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"string","enum":["submitted","awaiting_review","iterating","committed","rejected","abandoned"]},"proposed_fact":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"proposed_renderings":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"similar_fact_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"scores":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"iteration_count":{"type":"integer"},"submitted_by":{"type":"string","nullable":true},"reviewed_by":{"type":"string","nullable":true},"reviewer_feedback":{"type":"string","nullable":true},"committed_fact_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"reviewed_at":{"type":"string","nullable":true},"committed_at":{"type":"string","nullable":true}},"required":["id","input_kind","input_payload","status","proposed_fact","proposed_renderings","similar_fact_ids","scores","iteration_count","submitted_by","reviewed_by","reviewer_feedback","committed_fact_id","created_at","updated_at","reviewed_at","committed_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/forge/items/{id}/commit":{"post":{"summary":"Commit the chosen renderings: one fact and one question per format, in one transaction","description":"Role: admin.","tags":["forge"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"formats":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]+$"},"minItems":1},"fact_overrides":{"type":"object","properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"statement":{"type":"string","minLength":1},"subject":{"type":"string","nullable":true},"object":{"type":"string","nullable":true},"topic":{"type":"string","nullable":true},"era":{"type":"string","nullable":true,"enum":["ancient","medieval","modern","contemporary"]},"certainty":{"type":"string","enum":["verified","cited","unverified"]},"citation":{"type":"string","nullable":true}},"additionalProperties":false}},"required":["formats"],"additionalProperties":false}}}},"responses":{"200":{"description":"The item, committed","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"input_kind":{"type":"string","enum":["qa_pair","fact_statement","freeform"]},"input_payload":{"type":"object","additionalProperties":{"nullable":true}},"status":{"type":"string","enum":["submitted","awaiting_review","iterating","committed","rejected","abandoned"]},"proposed_fact":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"proposed_renderings":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"similar_fact_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"scores":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"iteration_count":{"type":"integer"},"submitted_by":{"type":"string","nullable":true},"reviewed_by":{"type":"string","nullable":true},"reviewer_feedback":{"type":"string","nullable":true},"committed_fact_id":{"type":"string","nullable":true,"format":"uuid"},"created_at":{"type":"string"},"updated_at":{"type":"string"},"reviewed_at":{"type":"string","nullable":true},"committed_at":{"type":"string","nullable":true}},"required":["id","input_kind","input_payload","status","proposed_fact","proposed_renderings","similar_fact_ids","scores","iteration_count","submitted_by","reviewed_by","reviewer_feedback","committed_fact_id","created_at","updated_at","reviewed_at","committed_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/audit":{"get":{"summary":"The audit log, newest first, filtered","description":"Role: admin.","tags":["audit"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"actor_id","in":"query"},{"schema":{"type":"string"},"required":false,"name":"actor_type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"action","in":"query"},{"schema":{"type":"string"},"required":false,"name":"action_prefix","in":"query"},{"schema":{"type":"string"},"required":false,"name":"target_type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"target_id","in":"query"},{"schema":{"type":"string"},"required":false,"name":"severity","in":"query"},{"schema":{"type":"string"},"required":false,"name":"after","in":"query"},{"schema":{"type":"string"},"required":false,"name":"before","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of audit entries","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"returned":{"type":"integer"},"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"occurred_at":{"type":"string"},"actor_type":{"type":"string","enum":["user","system","service","capability","api"]},"actor_id":{"type":"string","nullable":true,"format":"uuid"},"actor_label":{"type":"string","nullable":true},"action":{"type":"string"},"target_type":{"type":"string"},"target_id":{"type":"string","format":"uuid"},"context":{"type":"object","additionalProperties":{"nullable":true}},"severity":{"type":"string","enum":["info","notice","warning","error","critical"]},"client_event_id":{"type":"string","nullable":true}},"required":["id","occurred_at","actor_type","actor_id","actor_label","action","target_type","target_id","context","severity","client_event_id"]}}},"required":["limit","offset","returned","entries"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/audit/{id}":{"get":{"summary":"One audit entry","description":"Role: admin.","tags":["audit"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The entry","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"occurred_at":{"type":"string"},"actor_type":{"type":"string","enum":["user","system","service","capability","api"]},"actor_id":{"type":"string","nullable":true,"format":"uuid"},"actor_label":{"type":"string","nullable":true},"action":{"type":"string"},"target_type":{"type":"string"},"target_id":{"type":"string","format":"uuid"},"context":{"type":"object","additionalProperties":{"nullable":true}},"severity":{"type":"string","enum":["info","notice","warning","error","critical"]},"client_event_id":{"type":"string","nullable":true}},"required":["id","occurred_at","actor_type","actor_id","actor_label","action","target_type","target_id","context","severity","client_event_id"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/by-room-code/{code}":{"get":{"summary":"Look a session up by its room code (before joining)","description":"Role: public.","tags":["sessions"],"parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{4,8}$"},"required":true,"name":"code","in":"path"}],"responses":{"200":{"description":"The show a code opens","content":{"application/json":{"schema":{"type":"object","properties":{"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]}},"required":["room_code","show_name","theme","status"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/join":{"post":{"summary":"Join a session with its room code and a name; the reply holds your token","description":"Role: public.","tags":["sessions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"room_code":{"type":"string","pattern":"^[A-Za-z0-9]{4,8}$"},"display_name":{"type":"string","minLength":1,"maxLength":30},"remember_me":{"type":"boolean"},"device_token":{"type":"string","minLength":10,"maxLength":200}},"required":["room_code","display_name"],"additionalProperties":false}}}},"responses":{"201":{"description":"Joined; keep the token","content":{"application/json":{"schema":{"type":"object","properties":{"session":{"type":"object","properties":{"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]}},"required":["room_code","show_name","theme","status"]},"player":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"display_name":{"type":"string"}},"required":["id","display_name"]},"token":{"type":"string"},"device_token":{"type":"string"}},"required":["session","player","token"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions":{"get":{"summary":"List sessions, newest first","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of sessions","content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"returned":{"type":"integer"},"sessions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]},"settings":{"type":"object","additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","room_code","show_name","theme","status","settings","created_at","started_at","ended_at"]}}},"required":["limit","offset","returned","sessions"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Create a session (the night): a room code, in the lobby","description":"Role: admin.","tags":["sessions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"show_name":{"type":"string","minLength":1,"maxLength":80},"theme":{"type":"string","minLength":1,"maxLength":80},"settings":{"type":"object","additionalProperties":{"nullable":true}}},"required":["show_name"],"additionalProperties":false}}}},"responses":{"201":{"description":"The new session","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]},"settings":{"type":"object","additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","room_code","show_name","theme","status","settings","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}":{"get":{"summary":"One session with its players and its playlist","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The session","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]},"settings":{"type":"object","additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true},"players":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"display_name":{"type":"string"},"slot":{"type":"integer","nullable":true},"remembered":{"type":"boolean"},"joined_at":{"type":"string"},"left_at":{"type":"string","nullable":true}},"required":["id","session_id","display_name","slot","remembered","joined_at","left_at"]}},"games":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}},"required":["id","room_code","show_name","theme","status","settings","created_at","started_at","ended_at","players","games"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/end":{"post":{"summary":"End the night (a running game is abandoned)","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The session, ended","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]},"settings":{"type":"object","additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","room_code","show_name","theme","status","settings","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/abandon":{"post":{"summary":"Abandon the night: ended, and marked so","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The session, ended","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"room_code":{"type":"string"},"show_name":{"type":"string"},"theme":{"type":"string","nullable":true},"status":{"type":"string","enum":["lobby","in_progress","ended"]},"settings":{"type":"object","additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","room_code","show_name","theme","status","settings","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/players":{"get":{"summary":"A session's players, those who left too","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The players","content":{"application/json":{"schema":{"type":"object","properties":{"players":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"display_name":{"type":"string"},"slot":{"type":"integer","nullable":true},"remembered":{"type":"boolean"},"joined_at":{"type":"string"},"left_at":{"type":"string","nullable":true}},"required":["id","session_id","display_name","slot","remembered","joined_at","left_at"]}}},"required":["players"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games":{"get":{"summary":"A session's playlist, in play order","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The games","content":{"application/json":{"schema":{"type":"object","properties":{"games":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}},"required":["games"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}},"post":{"summary":"Add a game to the end of the playlist","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format_slug":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,40}$"},"pack_id":{"type":"string","format":"uuid"},"options":{"type":"object","properties":{"lifelines":{"type":"array","items":{"type":"string","enum":["fifty_fifty","ask_the_audience","phone_a_friend","ask_the_host","ask_the_presenter"]},"maxItems":5},"ladder":{"type":"array","items":{"type":"integer","minimum":1},"minItems":1,"maxItems":15},"safety_nets":{"type":"array","items":{"type":"object","properties":{"passed_index":{"type":"integer","minimum":0,"maximum":14},"payout":{"type":"integer","minimum":0}},"required":["passed_index","payout"],"additionalProperties":false},"maxItems":5}},"additionalProperties":false}},"required":["format_slug"],"additionalProperties":false}}}},"responses":{"201":{"description":"The queued game","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/start":{"post":{"summary":"Start a queued game with the players seated now (a late joiner waits, D43)","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"responses":{"200":{"description":"The game, in progress","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/end":{"post":{"summary":"End the running game now","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"responses":{"200":{"description":"The game, finished","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/abandon":{"post":{"summary":"Abandon the running game","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"responses":{"200":{"description":"The game, finished","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"position":{"type":"integer"},"format_slug":{"type":"string"},"options":{"type":"object","additionalProperties":{"nullable":true}},"pack_id":{"type":"string","nullable":true,"format":"uuid"},"status":{"type":"string","enum":["queued","in_progress","completed","abandoned"]},"result":{"type":"object","nullable":true,"additionalProperties":{"nullable":true}},"created_at":{"type":"string"},"started_at":{"type":"string","nullable":true},"ended_at":{"type":"string","nullable":true}},"required":["id","session_id","position","format_slug","options","pack_id","status","result","created_at","started_at","ended_at"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/adjust-score":{"post":{"summary":"Add to or take from a player's score","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"player_id":{"type":"string","format":"uuid"},"delta":{"type":"integer","minimum":-1000000,"maximum":1000000},"reason":{"type":"string","maxLength":200}},"required":["player_id","delta"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted and logged","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]},"seq":{"type":"integer"}},"required":["accepted","seq"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/override-ruling":{"post":{"summary":"Reverse a ruling on an answer","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target_event_id":{"type":"string","minLength":1,"maxLength":100},"new_ruling":{"type":"string","enum":["correct","incorrect","no_ruling"]},"reason":{"type":"string","maxLength":200}},"required":["target_event_id","new_ruling"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted and logged","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]},"seq":{"type":"integer"}},"required":["accepted","seq"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/skip-question":{"post":{"summary":"Skip the question on screen","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":200}},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted and logged","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]},"seq":{"type":"integer"}},"required":["accepted","seq"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/sessions/{id}/games/{gameId}/directive":{"post":{"summary":"Send the host a line (the Host console shows it)","description":"Role: admin.","tags":["sessions"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"gameId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"directive":{"type":"string","minLength":1,"maxLength":500},"target":{"type":"string","enum":["presenter","all_participants","players_only"]}},"required":["directive"],"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted and logged","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean","enum":[true]},"seq":{"type":"integer"}},"required":["accepted","seq"]}}}},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"409":{"description":"Conflicts with what is stored","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/ws/stage":{"get":{"summary":"Open the stage socket of a session (a WebSocket upgrade)","description":"Role: public.","tags":["sockets"],"parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{4,8}$"},"required":true,"name":"room","in":"query"}],"responses":{"101":{"description":"Switching protocols"},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The token is for another session, or the Origin is not ours","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"No open session has that room code","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"426":{"description":"Not a WebSocket upgrade","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/ws/host":{"get":{"summary":"Open the host socket of a session (a WebSocket upgrade)","description":"Role: admin.","tags":["sockets"],"parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{4,8}$"},"required":true,"name":"room","in":"query"}],"responses":{"101":{"description":"Switching protocols"},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The token is for another session, or the Origin is not ours","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"No open session has that room code","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"426":{"description":"Not a WebSocket upgrade","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/api/ws/play":{"get":{"summary":"Open the play socket of a session (a WebSocket upgrade)","description":"Role: public.","tags":["sockets"],"parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z0-9]{4,8}$"},"required":true,"name":"room","in":"query"}],"responses":{"101":{"description":"Switching protocols"},"400":{"description":"The request failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Not signed in, or not allowed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"403":{"description":"The token is for another session, or the Origin is not ours","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"404":{"description":"No open session has that room code","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"426":{"description":"Not a WebSocket upgrade","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}}}}