Grade the schema in the page and in CI.
Your documentation downloaded the schema to render it, so it can also tell you what is wrong with it. The same audit runs as a build check that fails the merge. Around it, patch what you don't own, and show every reader what moved since their last visit.
The demo schema's real report, drawn — one letter, seven categories, a link straight to every finding.
137 rules, seven categories, one letter.
Correctness against the OpenAPI specification, version by version. Security, each rule tied to the RFC or OWASP risk it breaks. Documentation, deprecation, consistency. Then two categories no generic linter has. Docs readiness is what will actually degrade in this rendered documentation: a missing summary is not a style point here, it is a blank line in your navigation. Agent readiness is what an AI agent gets when it calls your API through an MCP bridge or a GPT Action.
Each category scores, the document gets a grade from A to F, and every finding says why it matters and how to fix it. On the page, a finding links straight to the operation or schema it concerns: you read it, you click, you are looking at the problem. A file too broken to parse still gets a report, its syntax errors placed at their line and column.
Nothing is computed until someone opens #/audit, and nothing is sent anywhere: the analysis runs on the document the page already downloaded. Because it addresses the author rather than the reader, there is no navigation entry. The way in sits at the bottom of the settings drawer.
{ "features": { "audit": false } }
The same audit fails the build.
apiglow audit runs the same engine from the command line, so the grade your docs show is the grade your pipeline enforces. It exits non-zero on what it finds: a finding of a given severity, a grade or a score under your bar. It ships in the npm package; there is no ruleset to write and no service to sign up for.
An existing API adopts it without fixing its history first. A committed baseline records today’s findings, and the job fails only on new ones. An entry that no longer matches anything fails the run too, so a stale baseline never hides a regression.
The findings land where reviewers already look. SARIF for GitHub code scanning, annotations on the pull request’s diff, GitLab Code Quality in the merge-request widget, Markdown for the job summary. A versioned JSON report carries a stable fingerprint per finding plus each rule’s rationale and fix — what a script or a coding agent reads. Every finding is placed at file:line:column, through $refs into other files too. The package ships an agent skill that runs the audit, fixes the findings and audits again — without inventing what your API does.
On GitHub, apiglow/audit-action does it in one step. The docs carry recipes for GitLab, pre-commit, oasdiff and agents.
npx apiglow@0.3.0 audit openapi.yaml \
--baseline audit-baseline.json --min-grade B \
--format github --report sarif=audit.sarif
Your exceptions, written down.
A real API has deliberate exceptions. The audit block of the config switches a rule off or changes its severity, for the whole document or under some paths only — a frozen legacy API, a field that is public on purpose. The page and the command line read the same block, so the two grades agree.
A grade computed that way says so: it is labelled custom rule set next to the letter, in both exports and in the JSON. It never passes for the default one.
{ "audit": {
"rules": { "property-described": "off" },
"overrides": [{ "paths": ["/paths/~1legacy~1*"],
"rules": { "response-example": "off" },
"reason": "frozen legacy API" }]
} }
Patch a schema you don't own.
An OpenAPI Overlay 1.1 document is applied to the parsed source at load, before the Swagger 2.0 conversion — so a wrong description, a missing example or a bad tag is fixed in the docs without touching the file upstream or running anything beforehand.
Readers get their own overlay too. A reader can patch the schema from inside the documentation and then download the patch as a standard Overlay file — the fix, in a format the API’s owner can apply as-is. That turns “your docs are wrong” from a bug report into a pull request.
Endpoints can be hidden from the schema or from the config. That is documentation hiding, not access control: a hidden operation is absent from the rendered docs, and still very much present on your API.
Every reader gets their own changelog.
The documentation keeps a fingerprint of the operations each reader last saw — in their own browser — and diffs the loaded schema against it. A modal lists what was added, removed and changed since; badges mark it in the navigation and in the document itself, with accessible names, never colour alone.
There is no changelog service and no account. The comparison is against their last visit, not against a publication date you have to maintain, so the list is genuinely theirs.
The formats it actually reads.
OpenAPI 3.0, 3.1 and 3.2 render natively, including 3.2’s query method and $self. Swagger 2.0 is converted at load, with nothing to run beforehand. JSON Schema 2020-12 keywords are rendered rather than silently dropped, and circular references are handled — in the document and in the generated examples.
Webhooks and callbacks render like operations, with a simulator that can fire them, including a no-cors fire-and-forget mode.
What it is not.
The audit is not a general-purpose linter. It has no custom rules and no plugin system: its value is a rule set written for documentation, and you tune it rather than extend it. It does not detect breaking changes either — it grades one version of the document. Compare two versions with a diff tool such as oasdiff, next to it.
Hiding an endpoint hides it from the documentation. It is not security, and the page says so wherever the option appears.