📐 JSON Schema Validator
Validate JSON using JSON Schema. Displays errors with location information, including type mismatches, missing required properties, values outside enum, and regex violations. Supports Draft 7, 2019-09, and 2020-12.
Result will appear here.
🔗 Related Tools
📖 Where people get stuck
Runs JSON Schema (Draft 7, 2019-09 and 2020-12) through Ajv 8 and reports type mismatches, missing required properties, values outside an enum and so on, each with its field path. Everything runs in the browser. Zero errors does not mean the data is correct — a loose schema accepts anything. Nearly every difficulty people hit with JSON Schema comes down to a constraint they believe they wrote not actually being in force.
| Case | What happens | What to do |
|---|---|---|
| format email is declared but invalid addresses pass | format is an annotation by default and does not validate. That is not an implementation shortcut but the specification working as written: format assertion is defined as an optional vocabulary, so an implementation may ignore it and still claim conformance. Ajv is no different — without loading ajv-formats separately, email, date-time, uri and uuid all pass straight through. The awkward part is that the author believes it is validating while the runtime lets everything past, and nobody notices until production. |
On the server, always add ajv-formats — two lines: const addFormats = require("ajv-formats"); addFormats(ajv);. If portability matters more, a pattern regular expression is the safer choice and behaves identically in every implementation. (A complete regex for email addresses is not practical, so stop at something like ^[^@\s]+@[^@\s]+\.[^@\s]+$ and prove existence with a confirmation mail instead.) When you share a schema with anyone, state whether format is expected to be asserted — left implicit, the strength of the validation depends on whose implementation runs it. |
| required is declared but a missing property still passes | Almost always it is in the wrong place. required goes directly on the object schema, as an array of key names: {"type":"object","properties":{...},"required":["id","name"]}. Writing "required": true inside properties is Draft 3 syntax, and current drafts simply ignore it as an unknown keyword — it does not even raise an error, so nothing tells you. For the same reason, a typo such as requred or minLenght is silently ignored too. |
Run Ajv with strict: true. It then reports unknown keywords and contradictory type declarations as errors, which surfaces every constraint that was quietly doing nothing. Alongside that, write tests for the schema itself, and the key point is to include at least one document that must be rejected, not only documents that must pass — a suite of the latter alone passes against an empty schema. Required properties of a nested object belong inside that object schema; the parent required does not reach its children. |
| additionalProperties false is set yet extra keys still pass | It stops working the moment you combine it with allOf or $ref. The reason is that additionalProperties only looks at properties written in the same schema object. Inherit a base schema through allOf and set additionalProperties: false in the child, and even the properties the base defined count as additional, so valid data is rejected wholesale. Put it on the base instead and the properties the child adds get rejected. This is where more time disappears than anywhere else in JSON Schema, and using schema inheritance at all makes it nearly unavoidable. |
On 2019-09 and later, use unevaluatedProperties: false. It subtracts the properties already evaluated by allOf and $ref before judging, so it composes with inheritance — it is the keyword that was added precisely to fix this. If you must stay on Draft 7, dropping the inheritance and flattening the schema into one document at bundle time is quicker. Separately, whether an API should reject unknown keys at all is a design decision: rejecting them costs you forward compatibility, and adding one field breaks every existing client. Strict on input, tolerant on output (the Postel principle) is the safe default. |
Always write $schema. Omit it and the implementation picks a default draft for you, so the same schema means different things in different places. Draft 7 and 2020-12 differ notably in the array keywords: tuples — arrays whose positions have different types — moved from the array form of items to prefixItems, and feeding Draft 7 tuple syntax to a 2020-12 implementation applies the first type to every element of the array. No error is raised; only the meaning quietly changes. One more thing: do not trust data merely because it validated. JSON Schema guarantees shape, and business consistency — whether that id exists, whether the line items sum to the total — is outside its scope. Schema validation is a filter at the door, not a substitute for domain validation.
📖 How to Use
-
1
Enter your JSON SchemaPaste your JSON Schema (Draft 7 / 2019-09 / 2020-12) into the left textarea. Click Sample to load a working example.
-
2
Enter the JSON data to validatePaste the JSON data you want to validate into the right textarea. Validation runs automatically whenever either side is edited.
-
3
Review errors and fix themIf errors exist, they are listed with the field path, message, and params. Use them to fix either your JSON data or the schema.
❓ Frequently Asked Questions
Which Draft versions are supported?
Does format validation (email, date, etc.) work?
What is JSON Schema?
🐛 Found a bug or issue with this tool?
Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.
Thanks for your report!
Your report has been delivered to the operator and will be used to improve the tool.