NV ToolkitFormat · Validate · Convert

JSON Tools

JSON Schema Validator — Validate JSON Against a Schema

Paste a document and a JSON Schema, press Validate, and get every violation at once — each one located by its JSON Pointer path and named by the keyword that failed. Runs Ajv entirely in your browser.

In short

Validate a JSON document against a JSON Schema online. Ajv-powered, draft-07 / 2019-09 / 2020-12, with every error listed by JSON Pointer path and keyword.

By NaveenKumar T · Updated

Learn: How to Validate JSON Against a Schema in Python and JavaScript

  • Ajv engine — the reference JavaScript validator
  • draft-07, 2019-09 and 2020-12 schemas
  • All errors at once, not just the first

Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →

Why this tool

Syntax is not the same thing as correctness

A payload can parse perfectly and still be wrong for your API: a quoted number, a status your service never emits, a missing field. A schema is where those rules live, and this page is where you check them.

Every error, not just the first

Ajv runs with allErrors enabled, so one pass reports all the violations in the document. You fix a payload in a single edit instead of playing whack-a-mole with one message per run.

Errors located by path

Each line starts with a JSON Pointer — #/items/0/qty, #/customer/email — that points at the exact node inside your document, so nested arrays of objects stay debuggable.

Modern drafts supported

The draft is read from your schema's $schema keyword: 2019-09 and 2020-12 schemas are compiled with the 2020 Ajv build, everything else with draft-07. No selector to get wrong.

Nothing leaves the browser

The validator is downloaded to your machine and run there. Your document and your schema are never uploaded, which matters when the payload is a real customer record.

Learn more

Validate JSON against a schema, in the browser

A JSON document can be perfectly well-formed and still be wrong. It parses, the braces balance, every string is quoted — and the API still returns a 422, because the quantity arrived as the string "2" instead of the number 2, or because a status field carried a value the service has never heard of. Syntax checking, which is what a normal JSON validator does, cannot catch any of that. Schema validation can, because a JSON Schema describes the shape your data is supposed to have: which properties are required, what type each one is, which values are allowed, how long a string may be, how few items an array may contain.

This page pairs your document with your schema and runs them through Ajv, the validator that most of the JavaScript ecosystem already depends on — it is what Fastify, AJV-backed OpenAPI tooling and countless CI pipelines use under the hood. Because it runs with allErrors turned on, you get the complete list of problems in one pass rather than the first failure, which is the difference between one edit and six. And because everything happens in your browser, the payload you are debugging — often a real order, a real customer, a real webhook body — never leaves your machine.

The workflow is deliberately plain. Put the document in the large pane, the schema in the smaller one below it, and press Validate. A conforming document reports the draft that was used, a zero error count, and a census of the nodes that were checked. A non-conforming one reports each violation on its own line, sorted by path, in the form #/path — message (keyword). Switch the Output option to JSON when you want the raw Ajv error objects instead — params and all — to paste into a test fixture or an issue.

If you do not have a schema yet, generate a starting point from a sample payload with the JSON to JSON Schema converter and tighten it by hand, or read the JSON Schema tutorial for a walkthrough of the vocabulary. If the document will not parse at all, fix that first in the JSON Formatter, which points at the offending line.

The keywords a schema actually checks

JSON Schema has a large vocabulary, but a working schema is usually built from a dozen keywords. The table below covers the ones that appear in almost every real schema, what each one asserts, and the shape it takes in the schema document. Keywords are constraints, not declarations: a value is valid unless a keyword says otherwise, which is why an empty schema — {} — accepts absolutely anything, and why forgetting required is the single most common reason a broken payload sails through validation.

Two behaviours are worth internalising because they cause most of the surprise. First, type checks are strict about numbers versus strings: "2" is not 2, and integer rejects 2.5 while number accepts it. Second, required lists property names at the level of the object that owns them — it is not a flag you put inside each property — so a nested object needs its own required array to protect its own fields.

Common JSON Schema keywords
KeywordChecksExample
typeThe JSON type of the value: object, array, string, number, integer, boolean or null"type": "integer"
requiredProperty names that must be present on THIS object (missing ones are reported on the parent)"required": ["orderId", "total"]
enumThe value must be one of a fixed list — the usual way to model a status or a currency"enum": ["pending", "paid", "shipped"]
minimum / maximumNumeric bounds, inclusive (use exclusiveMinimum / exclusiveMaximum for open bounds)"minimum": 0
minLength / maxLengthString length in characters — good for codes, postcodes and free-text limits"maxLength": 140
patternThe string must match a regular expression; the only reliably enforced string constraint"pattern": "^ORD-[0-9]{5}$"
itemsThe schema every element of an array must satisfy (prefixItems for positional tuples in 2020-12)"items": { "type": "string" }
minItems / uniqueItemsArray length floor, and whether duplicate elements are allowed"minItems": 1, "uniqueItems": true
additionalPropertiesWhether keys you have not described are allowed; set false to lock an object down"additionalProperties": false
$refReuses another subschema by JSON Pointer — internal references only in this tool"$ref": "#/$defs/address"

Worked example: two rules, two errors

Here is the smallest schema worth writing: an object with an integer id and a status drawn from a fixed list, both required. It is the shape of half the records in any system — an identifier plus a state machine.

The document below parses without complaint. Nothing about it is malformed JSON. But the id arrived as a quoted string, which happens constantly when an identifier passes through a URL, a form field or a spreadsheet, and the status is a value that is not in the allowed set — a real bug, the kind that surfaces two services downstream when a switch statement falls through.

Validating one against the other produces exactly two lines, sorted by path. Read each one as: this location — this complaint (this keyword). The first says the value at #/id is not an integer; "42" is a string, and JSON Schema does not coerce. The second says the value at #/status is not in the enum, so either the payload is wrong or the schema needs "archived" added to its list — the validator tells you the rule that fired and leaves that judgement to you.

Note what is not reported: nothing about the missing properties, because none are missing, and nothing about extra keys, because the schema does not set additionalProperties: false. Both would be additional lines if the rules asked for them.

Schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "id",
    "status"
  ],
  "properties": {
    "id": {
      "type": "integer"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "closed"
      ]
    }
  }
}
Data
{
  "id": "42",
  "status": "archived"
}
Result
✗ Invalid — 2 errors

Draft         draft-07
Data nodes    3 (1 object, 0 arrays, 2 values)

#/id — must be integer (type)
#/status — must be equal to one of the allowed values (enum)

Reading the report: paths, keywords and drafts

The header of every report names the draft that was used and the size of the document that was checked, so you can confirm at a glance that your 2020-12 schema was not quietly compiled as draft-07. The node census — objects, arrays and scalar values — is a sanity check on the data pane: if you expected a hundred line items and it says four, you pasted the wrong payload.

Below the header, one line per violation. The path is a JSON Pointer, so #/items/2/qty reads as "the qty of the third element of items", and a bare # means the whole document failed. The keyword in brackets is the rule that fired, which is what you search for in your schema. Errors are sorted by path rather than by the order Ajv found them, which groups everything wrong with the same node together and makes long reports scannable.

One asymmetry catches everyone: a missing property is reported on its parent, not on itself, because the missing value has no path. So a line item without a sku appears as #/items/2 — must have required property 'sku' (required), not as #/items/2/sku. Type errors, enum errors and bounds errors all report on the value itself.

When you need more than the message — the allowed values of an enum, the limit a number exceeded, the pattern a string missed — switch the Output option to JSON. The report then appends the normalised error objects, each with its path, keyword, message and Ajv's params object, ready to paste into a test or an issue. That is also the form to keep if you plan to feed the result into another tool: explore it as a tree in the JSON Viewer, or reindent it with the JSON Formatter.

Help

Frequently asked questions

Everything you need to know about the JSON Schema Validator.

01Which JSON Schema drafts does this validator support?

draft-07, 2019-09 and 2020-12. The tool reads the $schema keyword at the top of your schema: if it names 2019-09 or 2020-12 the schema is compiled with Ajv's 2020 build (which understands prefixItems, unevaluatedProperties, dependentSchemas and $dynamicRef), and otherwise with the draft-07 build. A schema with no $schema keyword is treated as draft-07, which is the safest default because draft-07 syntax is a subset of what most tooling accepts. Draft-04 and draft-06 schemas are not compiled — they use the older exclusiveMinimum-as-boolean and id-instead-of-$id spellings — so migrate them to draft-07 first, which is usually a matter of renaming id to $id and rewriting exclusiveMinimum.

02Why doesn't my schema reject extra properties?

Because JSON Schema is permissive by default: any key you have not described is simply ignored. To forbid unknown keys, add "additionalProperties": false alongside the properties object at that level — it applies only to that object, so you have to repeat it on every nested object you want locked down. Two things surprise people. First, additionalProperties: false does not see keys matched by patternProperties at the same level, so combine them deliberately. Second, it does not combine well with allOf: a subschema inside allOf cannot see the sibling's properties, so "additionalProperties": false in one branch will reject fields that the other branch legitimately defines. If you only want a warning rather than a rejection, leave it off and use required plus tight property types instead.

03Does it follow $ref, and can I reference an external schema?

Internal references work exactly as the spec describes. A $ref like #/definitions/address (draft-07) or #/$defs/address (2019-09 and later) is resolved inside the same document, and recursive references are fine — a comment schema that contains an array of comments validates to any depth. External references to another file or a URL cannot be resolved here, because the validator runs in your browser with no network access to your schema store: a $ref pointing at https://example.com/address.json will fail to compile. The fix is to inline the referenced schema under $defs and point the $ref at it, which also makes the schema self-contained for anyone you share it with.

04What does a path like #/items/0/qty mean in the error list?

It is a JSON Pointer to the offending value: start at the document root (#), enter the items property, take element 0 of that array, then its qty property. Array positions are zero-based, so /items/0 is the first line item. A bare # means the failure is at the top level of the document — typically a type mismatch ("# — must be object") or a missing required key. Required-property errors are reported on the parent, not the missing child, so a missing sku on the third item appears as #/items/2 — must have required property 'sku'. The keyword in brackets at the end of each line tells you which rule failed — type, enum, minimum, required, additionalProperties — which is usually enough to find the rule in your schema.

05Why does one wrong field produce several errors?

Composition keywords report each branch they tried. A value described with oneOf, anyOf or allOf produces an error per failing branch plus a summary error for the composition itself, so a single bad value can turn into four lines. Read the deepest path first: the branch errors tell you what each alternative wanted, and the summary line just says none of them matched. The same happens with a nullable field written as {"type": ["string", "null"]} versus anyOf — the array form produces one clean error, the anyOf form produces three, which is a good reason to prefer the array form for simple nullability.

06Are format keywords like "email" or "date-time" enforced?

No. In JSON Schema, format is an annotation by default rather than an assertion, and this validator runs Ajv without the optional ajv-formats package, so an unknown or unenforced format is accepted and reported as valid. That is deliberate: format checking is where validators disagree most, and a page that silently rejected a legitimate email address would be worse than one that ignores the keyword. If you need the constraint enforced, express it as a pattern with a regular expression — "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$" for a loose email check — because pattern is an assertion in every draft and every implementation.

Keep working

Related tools

Learn the format

Related guides

All guides →