{"openapi":"3.1.0","info":{"title":"katago-ws","summary":"KataGo-backed SGF analysis service","version":"0.1.0"},"paths":{"/analyse":{"post":{"tags":["analyses"],"summary":"Submit an SGF for analysis","description":"Validates the SGF, persists a queued job, enqueues it, and returns the job id.","requestBody":{"content":{"text/plain; charset=utf-8":{}},"required":true},"responses":{"200":{"description":"The JSON body returned for any [`AppError`]: `{ \"error\": \"<message>\" }`.\nAlso the documented error schema for fallible endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/analyse/{id}":{"get":{"tags":["analyses"],"summary":"Get one analysis","description":"Returns the job status and, once done, the analysis result. Pass `?wait=<secs>` to long-poll until the job finishes (blocks up to the given budget, server-capped).","parameters":[{"in":"query","name":"wait","description":"Long-poll: maximum seconds to wait for the job to reach a terminal state\n(`done`/`failed`) before responding. When set, the request blocks until\nthe job finishes or this budget elapses (whichever first), then returns\nthe current state. Capped server-side. Omit (or `0`) to respond at once.","schema":{"description":"Long-poll: maximum seconds to wait for the job to reach a terminal state\n(`done`/`failed`) before responding. When set, the request blocks until\nthe job finishes or this budget elapses (whichever first), then returns\nthe current state. Capped server-side. Omit (or `0`) to respond at once.","type":"integer","format":"uint64","minimum":0},"style":"form"}],"responses":{"200":{"description":"Response to `GET /analyse/{id}`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}}}}},"/analyses":{"get":{"tags":["analyses"],"summary":"List analyses","description":"Lifecycle summary of every analysis job, newest first.","responses":{"200":{"description":"Response to `GET /analyses`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}}}}},"/workers":{"get":{"tags":["cluster"],"summary":"List connected workers","description":"Workers currently holding a live WebSocket session to this orchestrator. In-memory and per-instance (each orchestrator replica sees only its own); empty in the standalone role.","responses":{"200":{"description":"Response to `GET /workers`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkersResponse"}}}}}}}},"components":{"schemas":{"AnalysisSummary":{"description":"A single job's lifecycle state — the element of `GET /analyses` and the\npayload of each `GET /analyses/stream` event. Lightweight (no SGF/result).","type":"object","properties":{"created_at":{"description":"When the job was first queued (UTC, RFC 3339).","type":"string"},"error":{"description":"Failure detail, present when `status = failed`.","type":["string","null"]},"id":{"description":"Job id.","type":"string"},"status":{"description":"Current lifecycle state.","allOf":[{"$ref":"#/components/schemas/JobStatus"}]},"updated_at":{"description":"When the job last changed state (UTC, RFC 3339).","type":"string"}},"required":["id","status","created_at","updated_at"]},"ErrorBody":{"description":"The JSON body returned for any [`AppError`]: `{ \"error\": \"<message>\" }`.\nAlso the documented error schema for fallible endpoints.","type":"object","properties":{"error":{"description":"Human-readable error message.","type":"string"}},"required":["error"]},"JobId":{"description":"Path parameter for `GET /analyse/{id}`.\n\nA transparent `Uuid` newtype: it still deserializes/validates as a UUID, but\nis documented as a `string` in the OpenAPI spec (schemars 1.0 has no `Uuid`\nschema, so `Path<Uuid>` can't satisfy aide's `OperationInput` directly).","type":"string"},"JobStatus":{"description":"Lifecycle state of a job.","oneOf":[{"description":"Submitted and waiting to be picked up.","type":"string","const":"queued"},{"description":"Being analyzed by a worker.","type":"string","const":"running"},{"description":"Analysis finished successfully (carries a `result`).","type":"string","const":"done"},{"description":"Analysis was given up on after exhausting retries (carries an `error`).","type":"string","const":"failed"}]},"ListResponse":{"description":"Response to `GET /analyses`.","type":"object","properties":{"analyses":{"description":"All analysis jobs, newest first.","type":"array","items":{"$ref":"#/components/schemas/AnalysisSummary"}}},"required":["analyses"]},"StatusQuery":{"description":"Query parameters for `GET /analyse/{id}`.","type":"object","properties":{"wait":{"description":"Long-poll: maximum seconds to wait for the job to reach a terminal state\n(`done`/`failed`) before responding. When set, the request blocks until\nthe job finishes or this budget elapses (whichever first), then returns\nthe current state. Capped server-side. Omit (or `0`) to respond at once.","type":["integer","null"],"format":"uint64","minimum":0}}},"StatusResponse":{"description":"Response to `GET /analyse/{id}`.","type":"object","properties":{"error":{"description":"Failure detail, present when `status = failed`.","type":["string","null"]},"id":{"description":"Job id.","type":"string"},"result":{"description":"The analysis payload, present when `status = done`."},"status":{"description":"Current lifecycle state.","allOf":[{"$ref":"#/components/schemas/JobStatus"}]}},"required":["id","status"]},"WorkerSummary":{"description":"One connected worker in the `GET /workers` response.","type":"object","properties":{"connected_at":{"description":"When the session connected (UTC, RFC 3339).","type":"string"},"id":{"description":"Orchestrator-minted session id (not stable across the worker's reconnects).","type":"integer","format":"uint64","minimum":0},"name":{"description":"The name the worker registered with (from its `Hello`).","type":"string"},"peer":{"description":"Peer address (`host:port`), when the transport exposed one.","type":["string","null"]},"slots":{"description":"Max concurrent jobs the worker advertised on connect.","type":"integer","format":"uint32","minimum":0}},"required":["id","name","slots","connected_at"]},"WorkersResponse":{"description":"Response to `GET /workers`.","type":"object","properties":{"workers":{"description":"Workers connected to this orchestrator, oldest connection first.","type":"array","items":{"$ref":"#/components/schemas/WorkerSummary"}}},"required":["workers"]}}}}