GET /openapi.json
Returns a generated OpenAPI 3.0 document describing every registered public route — no authentication required, since it carries no data, only shape.
{id}-style) are exact, generated straight from the route registrations in internal/api/router_*.go by cmd/gen-openapi. Request and response bodies are a generic object placeholder rather than per-endpoint schemas — enough for API discovery and black-box fuzzing tools (e.g. schemathesis) to enumerate every operation, not enough to code-generate a typed client from. For the real request/response shapes, use the per-resource pages in this section.
/api/v1/internal/* routes are deliberately excluded — that surface is sidecar-only, X-Internal-Token authenticated (see Internal IPC), and this endpoint itself carries no auth. Publishing a route map of the one part of the API kept non-public would be counterproductive.
Methods not listed are rejected
If the spec lists onlyGET for a path, every other method on that path answers 405 Method Not Allowed with an RFC 9110 Allow header naming the methods that do work:
DELETE /api/v1/notifications/count reached the delete-notification handler with id="count" and answered 401/404 instead of 405. Twenty-nine paths behaved that way. A client can now trust the spec’s method list: what it does not list, the server refuses.
Response bodies are still the generic
object placeholder, and each operation still documents only 200. Error statuses (400, 401, 403, 404, 405, 409, 429, 500) are real and are listed under Common Status Codes — they are simply not yet enumerated per operation in the generated document. Treat the spec as authoritative for paths, methods and path parameters, and this reference section as authoritative for bodies and statuses.Before this endpoint existed,
GET /openapi.json returned 200 text/html — the embedded Next.js SPA answers every unmatched path with its index page. A status-code check alone can’t tell that apart from a real spec; check the Content-Type is application/json.