Skip to content

free_tool

Is your API contract production-ready?

An OpenAPI spec that renders fine in the docs viewer can still leave the API open by default, undocument every error, or hand clients an unbounded list. Paste yours and get a graded report on the design gaps that bite consumers, with the specific change to make for each one.

Runs entirely in your browser. Nothing is uploaded, sent to a server, or stored.

F

Spec quality

23/100

3 to fix · 6 warnings · 0 passed · 1 note · 3 operations

Grade F, score 23 out of 100, 3 to fix, 6 warnings, 0 passed.

Authentication is defined and applied

high

No security schemes, no global security requirement, and no per-operation security. The spec describes an unauthenticated API. If that is intentional (a public read-only API) you can ignore this, otherwise define a scheme and apply it.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
security:
  - bearerAuth: []

Operations document error responses

medium

2 operations document only success responses: GET /orders, POST /orders. A consumer then has no documented shape for a 4xx or 5xx and has to guess what an error looks like. Add at least one error response, or a "default".

responses:
  "200":
    description: OK
  "400":
    description: Bad request
  default:
    description: Unexpected error

Success responses define a content schema

medium

1 operation return a 2xx with a body but no content/schema: POST /orders. Without a media type and schema, generated clients and docs can't describe the payload. Add a content block with a schema.

responses:
  "200":
    description: OK
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/User"

Collection endpoints support pagination

medium

1 collection GET return an array but expose no pagination parameter (limit, offset, page or cursor): GET /orders. As the collection grows, an unbounded list response gets slower and heavier for every caller. Add pagination parameters.

parameters:
  - name: limit
    in: query
    schema: { type: integer, default: 20, maximum: 100 }
  - name: cursor
    in: query
    schema: { type: string }

Declares a real server URL

low

Every declared server points at a local or placeholder host (http://localhost:8080). Published consumers can't reach it. Add the real production server URL.

servers:
  - url: https://api.yourdomain.com/v1

Operations have a unique operationId

low

2 operations have no operationId: GET /orders, POST /orders. Code generators fall back to an awkward auto-name (like getUsersById_1), so client method names get unstable. Give each operation a stable, unique operationId.

get:
  operationId: listUsers

Operations have a summary or description

low

1 operation have neither a summary nor a description: POST /orders. The rendered docs then show a bare method and path with no explanation of what it does. Add a one-line summary.

get:
  summary: List all users
  description: Returns a paginated list of users.

info.title and info.version are present

low

Missing required info field: info.version. Both are required by the spec and are what docs and registries display as the API name and version. Set them.

info:
  title: My API
  version: 1.0.0

Array responses declare a maxItems bound

low

1 array response declare no maxItems, so the documented response size is unbounded: GET /orders. Pair the array with pagination, and set maxItems so consumers know the ceiling.

schema:
  type: array
  maxItems: 100
  items:
    $ref: "#/components/schemas/User"

OpenAPI version notes

Detected OpenAPI 3.0.3. This is a 3.0 document, where "nullable: true" and a single "example" are the idioms. If you move to 3.1, switch to JSON Schema 2020-12 nullability.

A clean spec is the contract, not the system. The auth model, the rate limits, the error envelope, the versioning and the backward-compatibility story are where an API ages well or breaks its consumers. That's the kind of review I do.

Get your API design reviewed: book a call

JSON specs are fully supported. YAML is parsed best-effort by extracting the fields a few rules need, so the response-schema, pagination and array-bound checks are skipped on YAML. For a complete lint, paste JSON. It runs entirely in your browser and uploads nothing.

why_it_matters

The spec is the contract every consumer codes against

A spec with no security block describes an open API, an operation with no 4xx or 5xx response hands clients no shape for failure, and a collection GET with no pagination parameter returns an unbounded list that gets slower for everyone as the data grows. None of these break the docs viewer, so they ship.

This linter reads the paths, operations, responses and servers and grades them against those design rules, plus the housekeeping that code generators rely on (a unique operationId, a real server URL, info.title and info.version). It is conservative: it only fails on what it can read in the spec, and warns for the context-dependent calls, so the obvious gaps get caught before a consumer files the bug.

faq

Questions & answers

What does the OpenAPI Spec Linter check?
It parses your OpenAPI 3.x document and grades it across security (a global or per-operation security requirement is defined and applied), responses (every operation documents an error response, and success responses define a content schema), design (collection GETs accept pagination parameters, operations have a unique operationId and a summary, array responses cap maxItems), and metadata (a real server URL, info.title and info.version). Each finding cites the path and method and gives the exact change to make.
Does it support YAML specs?
JSON is fully supported. YAML is parsed on a best-effort basis: the linter extracts the fields each rule needs with targeted, indentation-aware matching, so it can still check auth, error responses, pagination, operationIds, summaries, servers and info. The two checks that need to read deep into response schemas, the content-schema check and the array maxItems check, are skipped on YAML and marked n/a. For a complete lint, paste the spec as JSON.
Why does it flag my API as having no authentication?
Because the spec has no top-level security requirement, no per-operation security, and no securitySchemes under components, which describes an unauthenticated API. If the API really is public and read-only, that finding is safe to ignore. If schemes are defined but never referenced by a security block, the linter warns instead of failing, since defining a scheme does not apply it: an API with schemes but no security requirement is still open by default.
How does it decide an endpoint should support pagination?
It looks for GET operations whose path reads like a collection rather than a single item. A path ending in a parameter, like /users/{id}, is treated as an item and skipped; a path like /users or /users/{id}/orders is treated as a list. If such an operation declares no limit, offset, page, cursor or similar parameter, it warns, because an unbounded list response gets slower and heavier for every caller as the data grows. It is a heuristic from the path shape, so if a flagged GET actually returns a single object you can ignore that one.
Does it validate that my spec is syntactically valid OpenAPI?
No. It is a design-quality linter, not a full schema validator. It confirms the document is parseable and is OpenAPI 3.x rather than Swagger 2.0, then grades design and documentation gaps. It does not verify every $ref resolves, that schemas are well-formed, or that the document passes the full OpenAPI meta-schema. Run it alongside a structural validator, not instead of one.
Is my spec uploaded or stored anywhere?
No. The whole analysis runs in your browser. Nothing you paste is sent to a server or stored, so it is safe to lint a spec for an internal or unreleased API.

Want the API design looked at, not just the spec?

The spec is the contract. I'll review the auth model, rate limits, error envelope, versioning and the backward-compatibility story that decide whether the API ages well or breaks its consumers. Book a call, or leave your email.

Book a call

No spam. You'll get a reply from me.

Prefer proof first? See how this plays out in real case studies →