{"openapi":"3.1.0","info":{"title":"Roemeschke","version":"1","description":"A blog from Scott Roe-Meschke primarily oriented around software engineering leadership and development, building in the agentic age, and career learnings and lessons. Ask Scott's agent, and search the posts and pages. Every post is also markdown: add `.md` to its path (see /llms.txt)."},"servers":[{"url":"https://roemeschke.com"}],"security":[],"paths":{"/api/ask":{"get":{"operationId":"askDocs","summary":"How to ask Scott's agent, as markdown","responses":{"200":{"description":"The docs.","content":{"text/markdown":{}}}}},"post":{"operationId":"startConversation","summary":"Start a conversation with Scott's agent","description":"It answers questions about Scott and his writing, and passes messages on to him: opportunities, feedback on a post, questions. Agents are welcome.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequest"}}}},"responses":{"200":{"description":"The agent's reply.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskReply"}}}},"400":{"description":"The message isn't one: empty, too long, or not JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Held back: too many messages a minute, or agents' budget for the day is spent (the message isn't passed on). `line` says why; try again after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskReply"}}}}}}},"/api/ask/{conversation}":{"post":{"operationId":"continueConversation","summary":"The next message in a conversation","parameters":[{"name":"conversation","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"From the reply that started it."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskRequest"}}}},"responses":{"200":{"description":"The agent's reply.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskReply"}}}},"400":{"description":"The message isn't one: empty, too long, or not JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No such conversation, or it was forgotten after 90 quiet days.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"410":{"description":"The conversation has run its length. `line` says so; start a new one with POST /api/ask.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskReply"}}}},"429":{"description":"Held back: too many messages a minute, or agents' budget for the day is spent (the message isn't passed on). `line` says why; try again after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskReply"}}}}}}},"/api/search":{"get":{"operationId":"search","summary":"Search the posts and pages","description":"Finds posts, plus the about, privacy and site tech pages. It matches on words and meaning, then Jev reranks the results by how well they fit the search. You get each post or page once, linked to the section that matched best.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":200},"description":"What to look for, in words or as a question."},{"name":"quick","in":"query","schema":{"type":"boolean"},"allowEmptyValue":true,"description":"Skip the rerank: faster and rougher, for searching as someone types. Present means yes."}],"responses":{"200":{"description":"The posts and pages, best first. Empty when nothing matches.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResults"}}}},"400":{"description":"The search is too long.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many searches from one address. Try again after Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"AskRequest":{"type":"object","properties":{"message":{"type":"string","minLength":1,"maxLength":2000,"description":"What to say to scott's agent."},"turnstile":{"description":"A Turnstile token, which the site's own chat box sends to start a conversation with a human's limits. Agents leave it out.","type":"string"}},"required":["message"]},"AskReply":{"type":"object","properties":{"conversation":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Where the next message goes: POST /api/ask/{conversation}."},"line":{"description":"What the agent says. Absent when it stands by what it said last.","type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"href":{"type":"string","format":"uri","description":"The post."},"markdown":{"type":"string","format":"uri","description":"The same post as markdown."}},"required":["title","href","markdown"],"additionalProperties":false},"description":"Posts it suggests, to show under the line."},"failed":{"type":"boolean","description":"True when the agent couldn't answer (it's down, or a human's conversation is out of budget for the day): the line says so, and your message went to Scott as it was."}},"required":["conversation","links","failed"],"additionalProperties":false},"ApiError":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false},"SearchResults":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"href":{"type":"string","description":"The post's or page's path."},"markdown":{"type":"string","description":"The same post or page as markdown."},"date":{"description":"When the post came out. Pages have none.","type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},"snippet":{"type":"string","description":"A little of the post, around what matched."},"section":{"description":"The part of the post that matched best, when it isn’t the start.","type":"object","properties":{"heading":{"type":"string"},"href":{"type":"string"}},"required":["heading","href"],"additionalProperties":false},"relevance":{"description":"How likely this is what the search was after, as Jev read it. Absent when the results weren't reranked.","type":"number","minimum":0,"maximum":1},"status":{"description":"Not out yet. Only on staging and in development.","type":"string","enum":["draft","scheduled"]}},"required":["title","href","markdown","snippet"],"additionalProperties":false},"description":"Up to ten posts or pages (about, privacy…), best match first."}},"required":["results"],"additionalProperties":false}}}}