induwara.lk
induwara.lkDeveloper · Utility

JSON Schema Validator — validate JSON against a schema online

Paste a JSON document and a JSON Schema and see instantly whether it is valid — with the exact JSON Pointer path and a plain-English reason for every error. Supports drafts 2020-12, 2019-09 and draft-07. No signup, nothing uploaded, works offline.

By Induwara AshinsanaUpdated Jul 5, 2026
Validate JSON against a schema
JSON Schema draft
Load example

The data you want to check.

The contract the document must satisfy.

Paste a JSON document and a schema — or tap a Load example button — to see instant, line-by-line validation.
Runs fully in your browser — nothing is uploaded.

How it works

The validator runs five deterministic steps in your browser. No data is sent to a server, and the engine uses no eval, so it is safe under a strict Content-Security-Policy.

  1. Parse both inputs. The document and the schema each go through JSON.parse. If either is not valid JSON per the RFC 8259 grammar, the tool shows the parser message and the line and column of the syntax error, and stops before any schema rules run.
  2. Resolve the draft. If the schema declares a $schema keyword — for example https://json-schema.org/draft/2020-12/schema — that draft is used and the selector locks to it. Otherwise the draft you pick applies. The choice matters: keyword availability and semantics differ between drafts (for instance prefixItems exists in 2020-12 but not draft-07).
  3. Validate. The parsed document, schema and draft are fed to a dependency-free validator that evaluates each assertion keyword — type, required, enum, minimum, maxLength, pattern, format, oneOf, additionalProperties and the rest — per the JSON Schema Validation vocabulary.
  4. Collapse to the real failure.The raw engine output includes structural wrappers such as “property X does not match schema.” Those are folded away so each row points at the leaf assertion that actually failed. Combinators like oneOf keep their summary message instead of the noisier per-branch errors.
  5. Report. An empty error list means Valid. Otherwise you get an Invalidbadge, a count such as “3 errors in 2 locations,” and a table pairing each RFC 6901 pointer with a sentence like /age must be ≥ 18 (minimum). Turn on “Stop at first error” to short-circuit at the first failure instead of collecting all of them.

The engine passes the official JSON-Schema-Test-Suite for every supported draft. As an extra guard, 6 hand-computed worked examples are re-checked against their expected error lists on each build, so the error output stays reproducible. Supported drafts:

  • Draft 2020-12Current draft. Uses prefixItems for tuples; items applies to all remaining items.
  • Draft 2019-09Introduced $defs, dependentRequired, and unevaluatedProperties.
  • Draft-07Widely deployed. Tuple validation uses an array-valued items; supports if/then/else.

Worked examples

A numeric bound fails

2020-12Invalid ✕

Schema

{
  "type": "object",
  "required": ["name", "age"],
  "properties": {
    "name": { "type": "string" },
    "age":  { "type": "integer", "minimum": 18 }
  }
}

Document

{ "name": "Nimal", "age": -5 }
  1. name is a string → the name rule passes.
  2. Both required keys (name, age) are present → required passes.
  3. age is -5, and -5 < 18 → the minimum rule at /age fails.
  4. Result: 1 error → /age must be ≥ 18 (minimum).

enum plus a missing required property

draft-07Invalid ✕

Schema

{
  "type": "object",
  "required": ["status", "id"],
  "properties": {
    "id":     { "type": "string" },
    "status": { "type": "string", "enum": ["active", "inactive"] }
  }
}

Document

{ "status": "pending" }
  1. status is "pending", which is not in ["active","inactive"] → enum at /status fails.
  2. id is absent → required at the root fails.
  3. Result: 2 errors in 2 locations.
  4. (root) is missing required property "id" (required); /status must be one of ["active","inactive"] (enum).

An at-boundary value (edge case)

2020-12Invalid ✕

Schema

{
  "type": "object",
  "properties": {
    "order": {
      "type": "object",
      "properties": {
        "total": { "type": "number", "exclusiveMinimum": 0 }
      }
    }
  }
}

Document

{ "order": { "total": 0 } }
  1. exclusiveMinimum: 0 requires total to be strictly greater than 0.
  2. total is exactly 0, and 0 is not > 0 → the assertion fails.
  3. A plain minimum: 0 would pass here — the exclusive form is the difference.
  4. Result: 1 error → /order/total must be greater than 0 (exclusiveMinimum).

Frequently asked questions

Sources & references

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a bug, edge case, or want to suggest an improvement?

Email me at [email protected] — most fixes ship within 24 hours.