BV
All tools
developer

OpenAPI Validator

Validate an OpenAPI 3.x or Swagger 2.0 specification in JSON or YAML. Catches schema errors, unresolved $refs and missing required fields before they break code generation or a gateway import.

Muhammad Bilal
Muhammad Bilal Virk
5 min read
Live tool

Paste your OpenAPI specification in JSON or YAML and validate it against the OpenAPI 3.x or Swagger 2.0 rules. You get the errors, unresolved references and best-practice warnings, with enough detail to fix them.

Why an invalid spec costs more than it looks

A specification is not documentation with extra steps. It is the input to a chain of tools that will each fail differently when it is wrong: SDK and client generators, Swagger UI and Redoc, TypeScript type generation, contract testing, and gateway imports on AWS API Gateway, Kong or Apigee.

The expensive part is that most of those tools fail partially. A generator will happily emit a client for the fifteen endpoints it understood and quietly skip the one with the broken $ref. You find out when the method you needed is not there.

OpenAPI Validator — illustration

What "valid" means here

The specification is maintained by the OpenAPI Initiative, and the current release is OAS 3.2.0. Version 3.x and Swagger 2.0 are different formats rather than different editions — swagger: "2.0" at the top means the 2.0 rules apply, openapi: "3.x.y" means the 3.x rules do. Pasting a 3.x document into a 2.0-only tool produces error messages that make no sense until you notice the mismatch.

Schema definitions in OAS 3.1 and later align with JSON Schema 2020-12, which is why keywords that were rejected in 3.0 are accepted in 3.1 and above. If a spec validates in one tool and not another, check which version each assumes before assuming either is broken.

A worked example

Here is a minimal 3.1 document that validates:

text
openapi: 3.1.0
info:
  title: Leads API
  version: 1.2.0
paths:
  /leads/{id}:
    get:
      operationId: getLead
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: The lead
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Lead" }
        "404":
          description: No such lead
components:
  schemas:
    Lead:
      type: object
      required: [id, email]
      properties:
        id: { type: string }
        email: { type: string, format: email }

Four details in that are the ones people get wrong. A path parameter must have required: true — it is not optional and not implied. Every response needs a description; it is a required field, not a nicety. Status codes are quoted strings, because YAML will otherwise read 200 as a number and the document will fail in a way the error message does not explain. And operationId is technically optional but is what every generator uses to name the method, so leaving it out means your SDK gets getLeadsIdGet instead of getLead.

Errors this catches, in the order they usually appear

Error Why it happens Fix
Missing info.title or info.version Spec assembled by hand Both are required, always
Unresolved $ref Schema renamed in components, reference not updated Refs are case-sensitive and must match exactly
Unquoted status code YAML parses 200 as an integer Quote every response key
Response with no description Assumed optional Add one, even if it is a single word
Duplicate operationId Copy-paste between endpoints Must be unique across the whole document
Path parameter not declared Declared in the URL template only Every {param} needs a matching parameters entry
example disagreeing with schema Example written before the schema changed Validators warn; generators and mocks propagate the wrong shape
Security scheme referenced but not defined security used without components.securitySchemes Define it, or the gateway import silently drops auth

Mistakes that pass validation and still cause trouble

Everything returns 200. A spec with no error responses documented produces client code with no error handling. Document 400, 401, 404 and 429 — that is what consumers build against.

No pagination described. If a list endpoint is paginated in reality but not in the spec, every generated client will read the first page and report it as the whole result.

One giant file. Splitting into $ref files across a repository is normal and fine, but remember that some gateway imports require a single bundled document. Keep the split source and bundle for deployment.

A spec that has drifted from the implementation. The most dangerous state, because everything downstream is confidently wrong. Generating the spec from the code — as FastAPI does automatically — removes the whole category of problem, which is a large part of why it is a sensible default for an automation backend.

Frequently Asked Questions

Does a valid spec mean my API works?

No. Validation checks the document, not the service. An API can match its specification perfectly and still be broken, and it can work perfectly while the spec describes something else entirely. Send a real request with the API Request Tester and compare the response with what the spec promises — that comparison is the useful test.

Should I write the spec first or generate it from code?

Both work; mixing them does not. Spec-first suits teams where consumers need to start before the service exists, and pairs well with generating a mock from the document. Code-first suits a single team shipping quickly, and guarantees the spec matches reality. What fails is writing a spec by hand and then editing the code separately — they diverge within weeks.

JSON or YAML?

Whichever your team reads more comfortably; they are the same document. YAML is easier on the eye and has one real hazard, which is that unquoted values get type-guessed — 200, yes, no and on all become something other than the string you meant. If a YAML spec fails mysteriously, quote the suspicious values first.

Is Swagger 2.0 still worth using?

Only if a tool in your chain requires it. New work should target 3.1 or later. If you are converting an old document, expect the security definitions and the request body handling to need rewriting by hand — that part is not a mechanical translation.

How do I stop the spec drifting from the API?

Validate it in CI on every commit, and add a contract test that runs real requests against the documented shapes. Anything that only gets checked when someone remembers will eventually stop being checked.

Next steps

To exercise a specification before the backend exists, the API Mock Server turns a documented response into a live endpoint you can build against. For the backend side of the same job, Python FastAPI Webhook Automation covers building a service whose spec is generated rather than maintained, and API Automation for Businesses covers the wider integration picture.

If you are designing an API that has to plug cleanly into Make.com, n8n or a client's existing stack, that is work I take on as a freelancer — start a project on Fiverr or hire me on Upwork.

Muhammad Bilal
Muhammad Bilal Virk
AI automation engineer — building agents, workflows, and RPA that remove repetitive work.
Share
Newsletter

One email, when I ship something worth reading.

No cadence, no filler. Unsubscribe any time.

Free consultation

Want this built against your real numbers?

A 30-minute call to scope the workflow, agent, or automation you actually need.

Book a free consultation

More developer tools

All tools
Next step

Have a workflow that's burning hours every week?

Bring me one real bottleneck. I'll tell you whether it's worth automating, and what it would take.

Book 30 Minutes Call