{"openapi":"3.1.0","info":{"title":"Stoic Sage API","version":"1.0.0","description":"Semantic search and retrieval over a Stoic corpus: Meditations (Marcus Aurelius), On the Tranquillity of Mind and On the Shortness of Life (Seneca), and the Discourses, Enchiridion and Fragments (Epictetus). No authentication required for read endpoints."},"servers":[{"url":"https://stoicsage.ai"}],"paths":{"/api/search":{"get":{"summary":"Semantic-first hybrid search across the core Stoic sources.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":500},"description":"Natural-language query or citation (e.g. '6.26')."},{"name":"topK","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":20,"default":5}}],"responses":{"200":{"description":"Ranked results.","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"allOf":[{"type":"object","properties":{"source":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"]},"book":{"type":"integer"},"entry":{"type":"string"},"text":{"type":"string"}}},{"type":"object","properties":{"score":{"type":"number"},"weightedScore":{"type":"number"}}}]}}}}}}},"400":{"description":"Missing query parameter 'q'."},"429":{"description":"Rate limited (30/min per IP)."}}}},"/api/entry/{book}/{id}":{"get":{"summary":"Fetch a single entry by source, book/chapter, and entry id.","parameters":[{"name":"book","in":"path","required":true,"schema":{"type":"integer"}},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Entry id, may carry a letter suffix (e.g. '49a')."},{"name":"source","in":"query","required":false,"schema":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"],"default":"meditations"}}],"responses":{"200":{"description":"The entry.","content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"]},"book":{"type":"integer"},"entry":{"type":"string"},"text":{"type":"string"}}}}}},"404":{"description":"Entry not found."}}}},"/api/random":{"get":{"summary":"A weighted-random reflectable entry from any source.","responses":{"200":{"description":"Entry with view tracking.","content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"]},"book":{"type":"integer"},"entry":{"type":"string"},"text":{"type":"string"}}}}}}}}},"/api/daily":{"get":{"summary":"Today's date-seeded entry with pre-generated AI meditation.","responses":{"200":{"description":"Daily entry.","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"source":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"]},"book":{"type":"integer"},"entry":{"type":"string"},"text":{"type":"string"}}},{"type":"object","properties":{"meditation":{"type":["string","null"]},"rating":{"type":["integer","null"]},"viewId":{"type":"integer"}}}]}}}}}}},"/api/explain":{"post":{"summary":"Stream an advisor-style explanation of entries (Server-Sent Events).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query","entries"],"properties":{"query":{"type":"string","maxLength":500},"entries":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string","enum":["meditations","discourses","enchiridion","fragments","seneca-tranquillity","seneca-shortness"]},"book":{"type":"integer"},"entry":{"type":"string"},"text":{"type":"string"}}},"maxItems":10}}}}}},"responses":{"200":{"description":"SSE stream (text/event-stream).","content":{"text/event-stream":{}}},"400":{"description":"Body must include 'query' and 'entries'."},"429":{"description":"Rate limited (10/min per IP)."}}}},"/api/views/{viewId}/rating":{"put":{"summary":"Rate a viewed entry.","parameters":[{"name":"viewId","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rating"],"properties":{"rating":{"type":"integer","enum":[1,2,3]}}}}}},"responses":{"200":{"description":"Saved."},"404":{"description":"View not found."}}}}}}