How to validate a document
Paste the data into Document and the schema into Schema. Validation reruns as you type, and the status line says whether the document is valid and which draft was used. Every problem is listed with:
- the line in the document, which you can click to highlight the value and the rule that rejected it;
- the instance path, a JSON Pointer such as
/items/1/qty(/is the whole document); - a plain-English problem, e.g.
/age must be >= 0; - the schema path, such as
#/properties/age/minimum, so you can see which keyword fired.
All errors are reported, not just the first, and they are sorted by line. A missing required property is reported on the object that should contain it, while an unexpected property points at its own line. Both editors accept YAML as well as JSON, which suits schemas kept next to Kubernetes or CI files.
Drafts and the $schema keyword
The draft is read from the schema’s $schema URI: draft-04, draft-06, draft-07, 2019-09 or 2020-12. Without $schema the latest draft, 2020-12, is used, and the status line says so. The Draft menu overrides the detection when a schema declares the wrong one.
Drafts disagree in ways that change results. In draft-04, exclusiveMaximum is a boolean modifying maximum; from draft-06 on it is a number of its own. Draft 2019-09 renamed definitions to $defs, and 2020-12 replaced the array form of items with prefixItems. If a rule seems to be ignored, check that the draft in the status line is the one the schema was written for. The JSON Schema basics guide walks through the core keywords.
Formats are checked
The format keyword is validated, not just annotated: email, uri, uri-reference, date, time, date-time, duration, ipv4, ipv6, hostname, uuid, regex and json-pointer among others. Dates are checked against the calendar, so 2024-02-30 fails. A format name the validator does not know, such as phone, is ignored and listed as a warning rather than silently passing.
References, and why remote ones are not fetched
References inside the schema work: "$ref": "#/$defs/address", #/definitions/item in older drafts, and references to an $id declared within the same schema. References to the official meta-schemas also resolve.
A $ref to another URL, such as https://schemas.example.com/address.json, is not downloaded. Fetching it would tell a third-party server what you are working on, and this site never sends your data anywhere. Instead, a notice lists each remote reference and the schema line it is on, and that part of the schema accepts any value while the rest is still validated. To check it fully, paste the referenced schema into $defs and point the $ref at #/$defs/address. See Security for how the site is built.
Generate a schema to start from
No schema yet? Generate schema from document infers one from the document in the editor, using the same engine as the JSON to JSON Schema converter: every property seen becomes required, integer and number are told apart, and string formats such as date-time or email are added when every value matches. Treat it as a first draft. Loosen required for optional fields, add enum lists and minimum bounds, and decide whether additionalProperties should be false. If you don’t like the result, Ctrl+Z in the Schema editor restores the previous schema.
OpenAPI and Swagger documents
Switch to OpenAPI / Swagger to check an API description instead. The document is validated against the official schema for its version, detected from "openapi": "3.0.x", "3.1.x" or "swagger": "2.0", in JSON or YAML. Typical findings are a response without its required description, a path parameter missing required: true, or a misspelled field. Because OpenAPI’s schema uses many alternatives, a single mistake can produce two related messages; the first one listed is usually the one to fix.
Examples
A user record with five problems
An address without a domain, a negative age, a date that does not exist, a plan outside the enum and an unexpected property, each linked to its line. The website passes the uri format.
{
"id": "u_102",
"name": "Ada Lovelace",
"email": "ada@example",
"age": -4,
"website": "https://ada.dev",
"signupDate": "2024-02-30",
"plan": "platinum",
"nickname": "Countess"
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "User",
"type": "object",
"required": ["id", "name", "email", "plan"],
"properties": {
"id": { "type": "string", "pattern": "^u_[0-9]+$" },
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0 },
"website": { "type": "string", "format": "uri" },
"signupDate": { "type": "string", "format": "date" },
"plan": { "enum": ["free", "pro", "team"] }
},
"additionalProperties": false
}Draft-07 with definitions and a remote $ref
Items are checked through a local #/definitions reference, so the zero quantity is caught. The shipping address points at another server, which is listed but not fetched.
{
"orderId": 50021,
"items": [
{ "sku": "A-100", "qty": 2 },
{ "sku": "B-7", "qty": 0 }
],
"shipping": { "country": "DE", "postcode": "10115" }
}{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["orderId", "items"],
"properties": {
"orderId": { "type": "integer" },
"items": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/item" } },
"shipping": { "$ref": "https://schemas.example.com/address.json" }
},
"definitions": {
"item": {
"type": "object",
"required": ["sku", "qty"],
"properties": { "sku": { "type": "string" }, "qty": { "type": "integer", "minimum": 1 } }
}
}
}An OpenAPI 3.0 file in YAML
OpenAPI mode checks the API description itself. This response has content but no description, which OpenAPI 3.0 requires, so the error points at line 15.
openapi: 3.0.3
info:
title: Pet store
version: 1.0.0
paths:
/pets/{id}:
get:
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
content: {}
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
The document is missing required property "email" | A property listed in required is absent. Remember that required lives on the object schema, not inside the property. | Add the property to the document, or remove it from the required array if it is optional. |
The document has unexpected property "nickname" | The schema sets additionalProperties to false and the property is not declared in properties. | Declare it under properties, fix its spelling, or allow extra members by removing additionalProperties: false. |
The schema itself is invalid: schema is invalid: data/type must be equal to one of the allowed values | A keyword in the schema has an impossible value, such as “type”: “text” instead of “string”. | Use one of the JSON Schema types: string, number, integer, boolean, object, array or null. |
The schema itself is invalid: the reference #/$defs/address does not point at anything in the schema | The $ref names a definition that does not exist, often definitions versus $defs or a typo. | Check the spelling and the section name; draft-07 schemas usually use #/definitions/…, newer ones #/$defs/…. |
A remote $ref was not downloaded | The schema references a schema on another server. The validator never fetches anything, so that part accepts any value. | Paste the referenced schema under $defs and change the $ref to #/$defs/name to validate everything. |
Frequently asked questions
Which JSON Schema drafts are supported?
Draft-04, draft-06, draft-07, 2019-09 and 2020-12. The draft is taken from $schema, defaults to 2020-12, and can be overridden from the Draft menu.
Is my data or schema uploaded?
No. Ajv runs in a worker inside this tab, nothing is stored, and remote $ref URLs are deliberately not fetched, so the page makes no requests about your data.
Why does an invalid email pass?
The property needs “format”: “email” in the schema. Some validators treat format as a mere annotation; this one enforces it, so with the keyword present an address such as ada@example, which has no domain dot, is rejected.
Can I validate YAML against a JSON Schema?
Yes. Both editors accept YAML; it is converted to the same data model as JSON before validation, and errors still point at the YAML line.
What is the difference between the instance path and the schema path?
The instance path is where the bad value is in your document, as a JSON Pointer. The schema path is where the rule that rejected it is in the schema, which helps when several rules apply to one value.
Can it validate OpenAPI 3.1 and Swagger 2.0?
Yes. In OpenAPI mode the version is detected from the openapi or swagger field and the document is checked against the matching official schema.