The audit, rule by rule.
#/audit analyzes the schema the documentation already loaded — in the browser, nothing sent anywhere — and grades it. This guide explains what is checked, how the grade is computed, and what the report carries. The feature page is the overview.
Opening it, and switching it off
The audit addresses the API’s author, not its readers, so it deliberately gets no nav entry: the single entry point is a block at the bottom of the settings drawer, linking to #/audit — a real, copyable route you can open directly. Nothing is computed until that page is opened; the report is then cached in memory per spec.
features: { "audit": false } removes the route, the settings block and every computation — in multi-spec, per spec if you want: one API graded, its neighbor not.
What a finding carries
Every finding states a severity, a message, and a rationale — why it matters and what to do, in a sentence or two. Three severities:
| Severity | Claim |
|---|---|
error | Almost certainly a schema bug |
warning | Probably hurts consumers or the docs |
info | Worth knowing |
A finding on a rendered operation deep-links to it — you read the finding, you click, you are looking at the problem. A finding on a callback links to the operation that declares it (a callback has no route of its own), and a finding on a hidden operation shows a “hidden” badge instead of a dead link: the audit sees the full schema, but never links to a non-routable view. Findings elsewhere (components, info, …) show their JSON pointer.
The same omission repeated across a schema is one decision, not two thousand rows: findings are folded by rule, each row carrying its count, with occurrences materialized fifty at a time on expansion.
The five categories
Correctness — contradictions inside the document, mostly errors: a duplicated operationId, a path parameter missing from the template (or the reverse), required listing properties that don’t exist, an example or a default the declared schema itself rejects, a security requirement naming an undeclared scheme, a component defined but never referenced.
Documentation completeness — what the document leaves unsaid: operations without summary or description, undescribed parameters and properties, mutating operations documenting no error response at all, info missing its description, contact or license.
Deprecation hygiene — an inventory of everything deprecated: true, scored so the number reads as the share of the surface still current, plus a check that each deprecated element’s description names a replacement or a sunset.
Consistency — the document’s own conventions, held against itself: parameter and property names off the dominant naming convention (detected, not imposed — header names are exempt, they follow HTTP’s convention), mixed path-segment styles, the same schema written out inline in several places instead of shared.
Docs readiness — the category no generic linter has, because it measures how the schema behaves in this renderer. Each message names the concrete degradation: no operationId means unstable deep links, no servers means environment seeding has nothing to offer, an OAuth2 flow missing its URLs means the “Get a token” block cannot run, no example anywhere on an operation means try-it prefills fall back to generated samples, schema cycles deeper than the expansion budget mean readers will hit “expand” walls.
Version awareness
Rules judge the document against the version it declares, in both directions: a spelling a later version replaced (nullable: true from 3.1 on) and a construct used ahead of the declared version (webhooks or type arrays in a 3.0 document, 3.2-only constructs in a 3.1 one) are both correctness findings — while the same nullable in a 3.0 document passes, because it is correct there. A converted Swagger 2.0 document additionally gets one finding per construct the conversion could only approximate.
Scoring
Each rule application is a pass/fail check against a target — an operation, a parameter, a component, the document. From there:
- Category score = weighted pass rate over its applicable checks; weights by severity: error 3, warning 2, info 1.
- Not-applicable checks don’t count. An API with no deprecations scores 100% on deprecation hygiene, not zero; a category with no applicable check at all is absent from the report rather than scored.
- Letter grade from the mean of category scores: A ≥ 90, B ≥ 80, C ≥ 65, D ≥ 50, F below.
The report header shows the letter and per-category score bars; each category heading carries its own severity counts, so a section can be weighed without scrolling back.
The report names what it graded
Because a report is read out of context — a pasted screenshot, a tab left open — the page states its identity and perimeter: the API’s title, info.version and declared OpenAPI version, contact and license when the document carries them, and the document in figures: operations, groups, webhooks, security schemes, schemas. Counted on the document, so hidden operations are included; zeros are shown, because “no security scheme” is a thing the report goes on to grade.
Export
“Copy report as Markdown” carries everything the page shows — identity, figures, per-category counts, every finding with its rationale — plus a timestamp to the second: a pasted report outlives the schema it graded, and without a date a reader finding it in a ticket cannot tell whether it still describes anything. Two deliberate differences from the page: JSON pointers are kept whole (they locate the finding in the file you are about to edit), and the export travels in the language it was read in. Paste it into an issue, fix, reload, re-audit — and when the finding is in a schema you don’t own, overlays are the fix that needs no fork.