JSON Schema Validator

Validate a JSON document against a JSON Schema — with precise error paths, line/column locations and a schema health check.

Paste a JSON Schema on the left and the JSON document you want to check on the right. The document is validated in your browser against every keyword the schema uses — types, required properties, patterns, ranges, $ref references, allOf/anyOf/oneOf/not, if/then/else and more — and every failure is reported with the exact JSONPath ($.users[2].email) and JSON Pointer (/users/2/email) of the offending value, plus its line and column in your document. The draft is detected from $schema (draft-04 through 2020-12) and the schema itself gets a health check for typos, unresolvable references and invalid keyword values.

🔒 100% private — nothing is uploaded or stored. Both the schema and the document are validated entirely in your browser with plain JavaScript. Neither ever touches our servers, is written to disk, or leaves your machine — so you can validate production payloads, API responses and config files containing secrets without any data leaving your computer.

Schema (JSON Schema — draft-04 to 2020-12)

waiting for a schema

Document (the JSON to validate)

waiting for a document
Validates live as you type — or press Ctrl+Enter.

Options

In the JSON Schema spec, format is an annotation by default, but most validators treat it as a real check — pick errors, warnings or off. Deep uniqueItems compares {"a":1,"b":2} and {"b":2,"a":1} as equal; stringified does not.

Result

Paste a schema and a document to validate.

Schema health check

Schemas are code, and code has bugs. This pass walks your schema and flags things that will silently misbehave: $ref targets that don't resolve, unknown keywords (typos like requred), non-numeric bounds, invalid regexes and draft-specific keyword mismatches.

No schema to check yet.

Try a sample

How to read a validation error

Every error names three things: where, which rule and why. The path is a $-rooted JSONPath — object keys with dots, array indices in brackets — and the JSON Pointer is the same location in the RFC 6901 form that ajv, jsonschema and most API gateways emit, so the two notations always agree. The keyword is the schema rule that failed (required, type, maximum …) and the message states the expectation in plain English. Clicking the line/column jumps the document pane to the exact value that failed, which is the fastest way to fix real payloads: read the path, jump, fix, re-validate.

One subtlety: for required and similar "missing thing" errors there is no value at the path — the location then points at the object that should contain it, and the message names the missing property. For composition keywords (anyOf, oneOf) the summary row is followed by detail rows showing the first failure inside each branch, because "doesn't match any branch" is rarely actionable on its own.

Drafts at a glance

The $schema declaration selects the draft, and a few keywords changed meaning between drafts. This validator detects the draft from $schema and applies the right semantics (draft-07 is assumed when $schema is absent):

DraftWhat changed that matters
draft-04exclusiveMinimum/exclusiveMaximum are booleans that modify minimum/maximum; items is an array of positional schemas with additionalItems.
draft-06Same boolean exclusives as 04; minimum/maximum may be any number, not just integers.
draft-07Exclusives become numbers; adds contains, propertyNames and if/then/else. A $ref overrides sibling keywords.
2019-09$ref now applies alongside sibling keywords; $defs replaces definitions.
2020-12Positional array schemas move to prefixItems; items covers all items (and may be false to forbid items).

Common schema pitfalls

  • Forgetting required. properties only constrains keys that are present — an object with no properties still validates. Every optional-by-default key is a bug waiting to happen.
  • Leaving additionalProperties open. Without "additionalProperties": false, typos in key names (emial) pass silently. For strict APIs, close it.
  • integer vs number. 1.0 is an integer in JSON Schema (it has no fractional value), but 1.5 is not. If your API sends counts as floats, decide deliberately which one you want.
  • $ref and siblings. In draft-07 and earlier, keywords next to a $ref are ignored — a classic source of "my constraint does nothing". Use allOf to combine, or move to 2019-09+ where siblings apply.
  • enum with the wrong type. ["0"] (string) and [0] (number) are different enums. JSON has no type coercion — the values must match exactly.
  • Recursive schemas. $ref cycles are legal and supported here, but a runaway document will hit the recursion limit and report it as an error instead of hanging your browser.

Luke Keam
Thank you for reading. Get in touch
Luke Keam | techgeek.biz