Summary
Today website/docs/api/apiserver.md and parts of website/docs/api/router.md are hand-maintained. When apiserver routes change (routes_catalog.go, handlers, OpenAPI generation), the website docs drift — see #2772.
We already have a live machine-readable source of truth:
- Route catalog:
src/semantic-router/pkg/apiserver/routes_catalog.go
- Live OpenAPI:
GET /openapi.json (generateOpenAPISpec() in pkg/apiserver/openapi_spec.go)
- Live Swagger UI:
GET /docs
- Discovery index:
GET /api/v1
Goal: stop humans from editing API reference markdown for endpoint tables / request-response shapes. Generate those pages (or embed OpenAPI) from the catalog/OpenAPI, and fail CI when docs are stale.
Motivation
Proposed approach
Treat code + OpenAPI as source of truth; website markdown becomes generated or thin wrappers.
Phase 1 — Export OpenAPI artifact in CI/build
- Add a Make target, e.g.
make api-docs-openapi, that dumps the apiserver OpenAPI JSON/YAML to something like:
website/static/openapi/apiserver.openapi.json
- (optional)
docs/generated/apiserver.openapi.json
- Prefer generating from the same
generateOpenAPISpec() / route catalog used at runtime (unit-testable; no need to boot full router if possible).
- CI check: regenerated file must match committed artifact (
git diff --exit-code).
Phase 2 — Generate website API reference from OpenAPI
Pick one established path (recommend evaluating these):
| Option |
Fit |
Notes |
Docusaurus OpenAPI (docusaurus-plugin-openapi-docs / Redocusaurus) |
High |
Renders interactive reference from OpenAPI; common for Docusaurus sites |
Redocly (@redocly/cli build-docs) |
High |
Static HTML/MD from OpenAPI; good linting (redocly lint) |
| Custom generator from route catalog → Markdown tables |
Medium |
Reuses EndpointMetadata; good for compact tables + curated curl snippets |
| Swagger Codegen / openapi-generator |
Lower for docs |
Better for SDKs than narrative docs |
Recommended direction:
- Enrich OpenAPI with request/response schemas + examples where missing (today some paths are thin).
- Generate
website/docs/api/apiserver.md (or a generated sibling like apiserver.generated.md) from OpenAPI.
- Keep a small hand-written intro only (ports, auth overview, “how to run locally”) in a non-generated file that includes/embeds the generated reference.
- Mark generated files with a header:
DO NOT EDIT — generated by make api-docs-generate.
Phase 3 — CI automation on API surface changes
When PRs touch:
src/semantic-router/pkg/apiserver/**
- ExtProc public replay paths if documented (
router_replay*)
- OpenAPI generation code
Then CI should:
- Regenerate OpenAPI + Markdown (or fail if contributor didn’t run
make api-docs-generate)
- Optionally open/require a docs update via the stale-diff check
- Optionally run
redocly lint / OpenAPI contract tests
Also add a pre-commit or agent-harness hook for apiserver path changes → remind/run api-docs-generate.
Phase 4 — Router data-plane docs
website/docs/api/router.md covers Envoy :8801 (chat/completions, responses, router_replay). That surface is not fully in apiserver OpenAPI today.
Options:
- Extend OpenAPI (or a second OpenAPI doc) for ExtProc HTTP APIs (
/v1/router_replay*, etc.)
- Or keep a thin hand-written data-plane page that embeds generated sections where possible
Non-goals (initially)
- Auto-writing long narrative tutorials
- Replacing Swagger UI at
:8080/docs (keep it; website should align with it)
- Generating client SDKs in the first PR
Acceptance criteria
Suggested first PR scope
make api-docs-openapi + commit website/static/openapi/apiserver.openapi.json
- CI drift check
- Replace hand-maintained endpoint index in
apiserver.md with generated content (or OpenAPI plugin page)
- Follow-up: enrich OpenAPI examples (including
Idempotency-Key on POST /v1/router/outcomes)
Related
Labels (suggested)
documentation, enhancement, good first issue (for Phase 1 only) / help wanted
Summary
Today
website/docs/api/apiserver.mdand parts ofwebsite/docs/api/router.mdare hand-maintained. When apiserver routes change (routes_catalog.go, handlers, OpenAPI generation), the website docs drift — see #2772.We already have a live machine-readable source of truth:
src/semantic-router/pkg/apiserver/routes_catalog.goGET /openapi.json(generateOpenAPISpec()inpkg/apiserver/openapi_spec.go)GET /docsGET /api/v1Goal: stop humans from editing API reference markdown for endpoint tables / request-response shapes. Generate those pages (or embed OpenAPI) from the catalog/OpenAPI, and fail CI when docs are stale.
Motivation
Proposed approach
Treat code + OpenAPI as source of truth; website markdown becomes generated or thin wrappers.
Phase 1 — Export OpenAPI artifact in CI/build
make api-docs-openapi, that dumps the apiserver OpenAPI JSON/YAML to something like:website/static/openapi/apiserver.openapi.jsondocs/generated/apiserver.openapi.jsongenerateOpenAPISpec()/ route catalog used at runtime (unit-testable; no need to boot full router if possible).git diff --exit-code).Phase 2 — Generate website API reference from OpenAPI
Pick one established path (recommend evaluating these):
docusaurus-plugin-openapi-docs/ Redocusaurus)@redocly/cli build-docs)redocly lint)EndpointMetadata; good for compact tables + curated curl snippetsRecommended direction:
website/docs/api/apiserver.md(or a generated sibling likeapiserver.generated.md) from OpenAPI.DO NOT EDIT — generated by make api-docs-generate.Phase 3 — CI automation on API surface changes
When PRs touch:
src/semantic-router/pkg/apiserver/**router_replay*)Then CI should:
make api-docs-generate)redocly lint/ OpenAPI contract testsAlso add a pre-commit or agent-harness hook for
apiserverpath changes → remind/runapi-docs-generate.Phase 4 — Router data-plane docs
website/docs/api/router.mdcovers Envoy:8801(chat/completions, responses, router_replay). That surface is not fully in apiserver OpenAPI today.Options:
/v1/router_replay*, etc.)Non-goals (initially)
:8080/docs(keep it; website should align with it)Acceptance criteria
generateOpenAPISpecexamplesor a small curated overlay)make api-docs-generate→ commit artifactsSuggested first PR scope
make api-docs-openapi+ commitwebsite/static/openapi/apiserver.openapi.jsonapiserver.mdwith generated content (or OpenAPI plugin page)Idempotency-KeyonPOST /v1/router/outcomes)Related
/openapi.json,/docs,routes_catalog.go,openapi_spec.goLabels (suggested)
documentation,enhancement,good first issue(for Phase 1 only) /help wanted