OpenAPI Validator: Validate Your Spec Online for Free
Free OpenAPI validator for 3.0 and 3.1 — every structural error located by JSON Pointer, unresolved $ref references reported rather than skipped.
Try it now: OpenAPI Validator — Validate an OpenAPI 3.0 or 3.1 document and get every structural error located by JSON Pointer, with unresolved references reported rather than skipped.
What an OpenAPI Spec Is, and Why Validating It Isn't Pedantry
An OpenAPI document is a single YAML or JSON file that describes an HTTP API: every path, every operation, every request body and response shape, every parameter and its type. It's written once and then read by a surprising number of other tools — a client SDK generator turns it into typed request functions, a mock server turns it into fake responses for a frontend team to build against before the backend exists, a documentation site renders it as a browsable reference, and a CI pipeline diffs two versions of it to catch a breaking change before it ships. None of those tools read the API's actual code. They read the spec.
That's the whole reason an openapi validatormatters beyond satisfying a linter. The spec is a contract every downstream tool consumes, and a subtly invalid spec doesn't fail once, in one obvious place — it fails somewhere else, in a tool that has nothing to do with where the mistake actually is. A missing responseskey on one operation might not break anything visible until a client generator silently emits a method with no return type, or a mock server serves an empty 200 for an endpoint that's supposed to return a 404. By the time someone notices, they're debugging the generated client, not the three-line spec typo that caused it.
Validating early — before the spec is handed to any of those tools — turns a confusing, distant failure into an error message at the source, with a precise location. That's the entire value proposition of GenKitLab's OpenAPI validator: it checks the document itself, structurally, against the specification it claims to follow, and reports exactly where it diverges.
OpenAPI 3.0 vs. 3.1: What Actually Changed
Most specs in the wild are still 3.0.x, but 3.1 has been out since 2021 and shows up often enough that knowing the real differences — not just "it's newer" — matters for anyone running an openapi 3.1 validator against a document for the first time.
The headline change is that OpenAPI 3.1 fully aligns its schema dialect with JSON Schema 2020-12. OpenAPI 3.0 used a schema object that looked like JSON Schema but was actually a constrained subset with its own quirks, one of which trips people up constantly: nullability. In 3.0, a field that can be a string or null is written with a separate nullable keyword bolted onto the type:
middleName: type: string nullable: true
In 3.1, that keyword is gone entirely — because 3.1's schema object is JSON Schema 2020-12, and JSON Schema has always expressed this with a type array instead of a bolted-on flag:
middleName: type: [string, "null"]
Mixing these up is the single most common 3.0-vs-3.1 mistake: pasting a nullable: true field into a document declared as openapi: 3.1.0doesn't raise a loud error in every tool, but a strict validator running against the 3.1 meta-schema will flag nullable as an unrecognized keyword there, since it was never part of JSON Schema in the first place.
The second real difference is that 3.1 adds first-class support for webhooks — a top-level webhooks object, sitting alongside paths, that describes requests the APIsends to a callback URL a consumer registers, rather than requests it receives. 3.0 had no clean way to document this; teams either left it out of the spec entirely or abused the callbacks field, which describes something narrower and operation-specific. A document that's valid 3.1 with real webhook definitions won't downgrade to 3.0 without restructuring that section.
Everything else — path templating, parameter objects, security schemes, the overall document shape — is close enough between the two versions that most specs migrate with minor edits. The nullable-field rewrite is the one that actually requires touching every affected schema by hand.
What 'Validate' Actually Checks
It's worth being precise about what a structural validator is doing, because it's doing less than "is this a good API" and more than "is this valid YAML." A validator checks a document against the OpenAPI meta-schema — the formal definition of what a legal OpenAPI document looks like — for things like:
- Required top-level fields are present — every OpenAPI document needs an
info.titleand aninfo.version, and at least one ofpathsor (in 3.1)webhooks. Miss any of these and the document isn't a valid OpenAPI spec, full stop, regardless of how correct everything else is. - Fields have the right type —
info.versionhas to be a string (even if it looks like a number, e.g."1.0"),requiredon a schema has to be an array, not a boolean. - Enum-constrained fields hold a valid value — a parameter's
infield can only bequery,header,path, orcookie. Anything else is invalid, not just unusual. - Every
$refactually resolves — covered in detail below, and the point this tool treats as non-negotiable.
What that list deliberately doesn't include: whether your API design is good. A spec can be 100% structurally valid — every required field present, every type correct, every reference resolved — and still describe a badly designed API: inconsistent naming across endpoints, a resource with no way to delete it, a 200 response that returns an error object. Structural validation catches malformed contracts; it says nothing about whether the contract itself makes sense. That second kind of review is a design discussion, not a lint pass — a validator's job stops at "this document says what it claims to say, in the shape the spec requires," not "this is a well-designed API."
The One Thing Most Validators Get Wrong: Unresolved References
This is the detail that separates a validator you can actually trust from one that gives you false confidence. An OpenAPI document leans on $ref constantly — a request body pointing at #/components/schemas/User, a response pointing at a shared error schema, a parameter defined once and referenced from a dozen operations. Every one of those references has to resolve to something that actually exists.
paths:
/users/{id}:
get:
responses:
"200":
description: A single user
content:
application/json:
schema:
$ref: "#/components/schemas/Usr" # typo — the component is "User"
components:
schemas:
User:
type: object
properties:
id:
type: stringThat's a single-character typo — Usr instead of User— and it's exactly the kind of mistake that's trivial for a human to miss on a skim but breaks anything that actually tries to resolve the schema.
Here's the part worth sitting with: some validators, faced with a reference they can't resolve, simply skip validating whatever depends on it and report success on everything else. That is worse than not validating at all, because it produces a clean-looking report while an entire branch of the document — potentially every field on that schema — was never actually checked. A spec with a green checkmark that quietly skipped validating half its schemas isn't a validated spec; it's an unvalidated one wearing a validated one's badge.
GenKitLab's validator treats an unresolved $ref— whether it points at a missing component, a broken relative file path, or a fragment that doesn't exist in the target document — as an explicit, reported error, located by JSON Pointer, exactly like any other structural failure. Nothing is silently skipped. If a reference doesn't resolve, that's the finding, not a reason to look away from everything downstream of it.
Common Errors, With Real Examples
Three mistakes account for a large share of what actually shows up when you validate openapi documents pulled from real projects. Each one is small in the source file and easy to miss on a read-through.
1. Missing required info.version
openapi: 3.1.0
info:
title: Order Service API
# version is required and absent here
paths:
/orders:
get:
responses:
"200":
description: A list of ordersError at /info: missing required property "version"
info.versiondescribes the API's own version — not the OpenAPI spec version, which is the separate top-level openapifield — and it's required by the meta-schema regardless of whether anything downstream actually reads it.
2. An operation with no responses key
paths:
/orders/{id}:
get:
summary: Fetch a single order
parameters:
- name: id
in: path
required: true
schema:
type: string
# responses is required on every operation object and is missing hereError at /paths/~1orders~1{id}/get: missing required property "responses"Notice the JSON Pointer: /paths/~1orders~1{id}/get. The forward slashes inside the path key /orders/{id} are escaped as ~1 per the JSON Pointer spec (RFC 6901), since an unescaped slash would otherwise be read as a path separator in the pointer itself. Every operation object needs at least one entry under responses, even if it's just a defaultcase — there's no such thing as an operation that documents no possible response.
3. An invalid in value on a parameter
parameters:
- name: session_id
in: cookie2 # must be one of: query, header, path, cookie
required: true
schema:
type: stringError at /paths/~1account/get/parameters/0/in: value "cookie2" is not one of the enum values: "query", "header", "path", "cookie"
This one usually comes from a typo or from copy-pasting a parameter object between specs without updating the placement. Because inis enum-constrained, there's no ambiguity about what the fix is — just no forgiveness for anything outside the four allowed values, either.
What a Valid OpenAPI 3.1 Path Looks Like
Putting the corrected pieces from above together, here's a minimal but fully valid OpenAPI 3.1 path definition — a single operation with a resolvable reference, a properly typed path parameter, and a complete responses object:
openapi: 3.1.0
info:
title: Order Service API
version: "1.0.0"
paths:
/orders/{id}:
get:
summary: Fetch a single order
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: The requested order
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"404":
description: No order exists with that ID
components:
schemas:
Order:
type: object
required: [id, status, total]
properties:
id:
type: string
status:
type: string
enum: [pending, shipped, delivered, canceled]
total:
type: number
note:
type: [string, "null"]That last field, note, is the 3.1-specific nullable pattern from earlier in this article — worth checking any time you migrate a 3.0 spec, since that's the field type most likely to get overlooked.
GenKitLab vs. Swagger Editor vs. Generic Online Validators
| GenKitLab | Swagger Editor | Generic online validators | |
|---|---|---|---|
| Runs client-side, no upload | Yes — validation runs entirely in your browser | The hosted editor.swagger.io instance sends your document to a remote server by default | Varies by site; many post the pasted document to a backend to validate it |
| OpenAPI 3.0 and 3.1 support | Both, including the JSON Schema 2020-12 dialect 3.1 requires | 3.1 support has historically lagged behind 3.0 in the editor's bundled tooling | Inconsistent — some tools were built against 3.0 only and misreport valid 3.1-specific syntax as errors |
| Errors located by JSON Pointer | Yes — every error names the exact pointer into the document | Line-and-column in the editor pane, not a portable JSON Pointer | Often a generic message with no precise location at all |
| Unresolved $ref explicitly reported | Yes — treated as a hard error, never silently skipped | Depends on context; some broken relative-file references only surface when a separate tool tries to bundle the spec | Frequently skipped — a whole branch of the document goes unchecked with no indication it happened |
| Sign-up required | No | No, for the open-source editor | Varies — some gate results or rate-limit without an account |
Swagger Editor is the closest thing to an industry standard and it's a genuinely capable tool, particularly for editing a spec interactively with live preview. The gap that matters most for a quick swagger validator check is upload: the hosted instance most people reach for sends the document to a remote server, which is a real consideration for a spec that documents an unreleased API or embeds internal server names. GenKitLab's OpenAPI validator runs entirely in your browser — nothing you paste or upload is ever transmitted anywhere — and reports every structural error, including unresolved references, located precisely by JSON Pointer.
Explore More OpenAPI Tools
Validating is usually one step in a small workflow around a spec. Two tools that pair naturally with it:
- Swagger & OpenAPI Formatter — once a spec validates cleanly, convert it between YAML and JSON and put every key back into specification order, useful before committing it or handing it to a teammate.
- OpenAPI Diff Checker — compare two versions of a spec and see which changes actually break existing clients, the natural next check once you've confirmed both versions are individually valid.
See the full OpenAPI tools category for the rest of the spec-authoring workflow.
Frequently asked questions
›What does an OpenAPI validator actually check?
Structural correctness against the OpenAPI meta-schema: required fields are present (info.title, info.version, at least one path or webhook), field types are correct, enum-constrained values like a parameter's in field hold a legal value, and every $ref resolves to something that actually exists. It does not judge whether the API design itself is good — a structurally valid spec can still describe a poorly designed API.
›What's the difference between OpenAPI 3.0 and 3.1?
The two changes worth knowing precisely: 3.1 fully aligns its schema dialect with JSON Schema 2020-12, so a nullable field is written as a type array like ["string", "null"] instead of 3.0's separate nullable: true keyword. And 3.1 adds first-class webhook support via a top-level webhooks object, describing requests the API sends out rather than receives.
›Why does an unresolved $ref matter so much in validation?
Because a validator that silently skips a broken reference — instead of reporting it — gives false confidence that a spec is clean when an entire branch of it was never actually checked. That's worse than not validating at all, since the report looks green while real structural problems downstream of that reference go undetected. GenKitLab's validator reports every unresolved reference explicitly, whether it's a missing component or a broken relative file path.
›Is Swagger a different thing from OpenAPI?
Swagger was the original name of the specification before it was donated to the Linux Foundation and renamed OpenAPI at version 3.0. "Swagger" now mostly refers to the older 2.0 spec format and to tooling names that kept the word, like Swagger Editor and Swagger UI, which both support modern OpenAPI 3.x documents despite the name.
›Can a spec be valid OpenAPI but still a bad API design?
Yes, and this is worth being precise about. Structural validation confirms the document matches the meta-schema — required fields present, correct types, resolvable references. It says nothing about whether the API itself makes sense: inconsistent naming, a resource with no delete operation, or a 200 response returning an error object can all coexist with a perfectly valid spec. That's a design review, not a validation pass.
›Does this OpenAPI validator upload my spec anywhere?
No. Validation runs entirely client-side in your browser — the document you paste or drop in is parsed and checked locally, and nothing is transmitted to a server, which matters for a spec describing an unreleased API or one that embeds internal hostnames.
›What is a JSON Pointer, and why does the validator use it for error locations?
A JSON Pointer (RFC 6901) is a string like /paths/~1orders~1{id}/get that addresses one exact location inside a JSON or YAML document, with forward slashes in a key escaped as ~1. Reporting errors this way means every finding names the precise field that's wrong, rather than a vague line number or a generic "schema invalid" message.
›How do I validate an OpenAPI 3.1 spec specifically?
Use a validator that actually implements the 3.1 meta-schema rather than one built only against 3.0 — the two dialects diverge specifically around schema objects (JSON Schema 2020-12 alignment) and the webhooks field, so a 3.0-only validator can misreport valid 3.1 syntax, like a type array for nullability, as an error. GenKitLab's OpenAPI validator supports both 3.0 and 3.1 against their respective meta-schemas.
Last updated