JSON Schema Validator

Validate a JSON document against a JSON Schema (Draft 2020-12 by default). Errors point to the failing path with a human-readable reason — fully client-side via Ajv.

Loading…

All processing runs in your browser — no files or inputs are uploaded to a server.

How to use

Paste a JSON Schema on the left and the JSON document you want to check on the right. The validator runs Ajv (Another JSON Validator, the most-used JS library for this) with `allErrors: true` so every failing path is reported, not just the first one. Each error includes the JSON Pointer to the failing field, the schema keyword that rejected it (`required`, `type`, `minLength`, `format`, …), and a human-readable message. Validation runs as you type — paste, edit, watch errors flicker in and out.

Reach for this when designing an API contract, validating sample payloads against a published schema, or debugging why a webhook receiver keeps rejecting the body. The tool ships `ajv-formats` so the standard format checks work out of the box — `email`, `date-time`, `uri`, `uuid`, `ipv4`, `regex`. The schema and data never leave the browser, which matters when the payload contains internal field names or PII. For runtime use in your own code, the same Ajv library powers most server-side and CLI validators (`ajv-cli`, NestJS validation pipe, Fastify schemas).

Examples

Validate a basic user object

Input
schema:
{
  "type": "object",
  "required": ["id", "email"],
  "properties": {
    "id":    { "type": "integer", "minimum": 1 },
    "email": { "type": "string", "format": "email" },
    "tags":  { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
  }
}

data:
{ "id": 1, "email": "[email protected]", "tags": ["admin", "founder"] }
Output
✓ valid

The schema requires an integer `id` ≥ 1 and an email-formatted `email`; `tags` is optional but if present must be an array of unique strings. The data satisfies all three, so validation passes silently. Change the email to `"alice"` and the `format` keyword fires; remove the `id` field and `required` complains.

Multiple errors at once

Input
schema: (same as above)

data:
{ "id": -3, "email": "not-an-email", "tags": ["a", "a"] }
Output
✗ 3 errors
/id     minimum  must be >= 1
/email  format   must match format "email"
/tags   uniqueItems  must NOT have duplicate items (items ## 1 and 0 are identical)

With `allErrors: true` every failure surfaces at once instead of stopping at the first. JSON Pointers like `/id` and `/tags` point at the exact failing field; the `keyword` column tells you which schema rule fired so you can grep the schema source quickly.

Schema with `$ref` and `$defs`

Input
schema:
{
  "$defs": {
    "Address": {
      "type": "object",
      "required": ["city"],
      "properties": { "city": { "type": "string" }, "zip": { "type": "string", "pattern": "^[0-9]{5}$" } }
    }
  },
  "type": "object",
  "properties": {
    "home":   { "$ref": "#/$defs/Address" },
    "office": { "$ref": "#/$defs/Address" }
  }
}

data:
{ "home": { "city": "Seoul" }, "office": { "city": "Tokyo", "zip": "100-0001" } }
Output
✗ 1 error
/office/zip  pattern  must match pattern "^[0-9]{5}$"

`$defs` (formerly `definitions` before 2019-09) holds reusable subschemas; `$ref` includes them by JSON Pointer. The Tokyo zip code `100-0001` is the Japanese format (postal code with hyphen) but the schema enforces the US 5-digit format. Either loosen the pattern (`^[0-9-]{5,8}$`) or compose two address schemas — one US, one JP — and use `oneOf`.

FAQ

Which JSON Schema draft does this support?

Ajv 8 (the version this tool ships) defaults to Draft 2020-12, which is the current published draft as of mid-2026. It also reads Draft 2019-09, 07, and 06 with the right `$schema` declaration at the top of your schema. The big move between 07 and 2019-09 was renaming `definitions` to `$defs`, adding `$anchor`, and reworking how `$ref` interacts with sibling keywords. If your tooling chain still emits Draft 07, set `"$schema": "http://json-schema.org/draft-07/schema#"` and the validator switches modes.

How is JSON Schema related to OpenAPI?

OpenAPI uses JSON Schema as its body / parameter type system, but with caveats. OpenAPI 3.0 ships a *subset* of Draft Wright-00 with several extensions (`nullable`, `discriminator`, `xml`); OpenAPI 3.1 (May 2021) aligns fully with JSON Schema 2020-12. So 3.0 schemas are mostly portable but not strict JSON Schema, while 3.1 schemas validate cleanly. When migrating, the biggest gotchas are `nullable: true` (replaced by `type: [..., "null"]`) and the removal of `example` in favor of `examples` (an array).

What does `format: "email"` actually check?

It checks the syntax against a pragmatic regex, not full RFC 5321 compliance. Most addresses people actually type pass; a few exotic-but-legal forms (`"hello world"@example.com`, quoted local parts, IP-literal hosts) get rejected. JSON Schema deliberately leaves `format` semi-defined so implementations can pick their stringency. Treat it as "looks like a typical email" rather than "deliverable address" — for real verification you need to send mail and check the bounce.

Why do my error messages reference paths I do not have?

Two common causes. With `additionalProperties: false`, an unexpected field shows up as an error against the parent path, not the unknown field path — the validator does not know what to call it. With `anyOf` / `oneOf`, the validator reports errors against every branch that failed, so a single bad value can generate three or four error rows all pointing to the same place from different angles. Read the `keyword` column to find which branch you actually wanted to satisfy.

Can the tool generate sample data from a schema?

No — this tool validates only. Mock generation from a schema is a different problem (`json-schema-faker`, `Mockoon`, `jsf` CLI) and involves inferring sensible defaults, randomizing within constraints, and handling `enum` / `format` smartly. Some schemas validate but have no constructive solution (e.g., `not: { type: "string" }` accepts any non-string), and good generators handle those gracefully.

Strict mode is off — does that matter?

Ajv's strict mode rejects schemas with unknown keywords or non-permitted constructs (for example a `format` keyword on a non-string `type`). This tool runs with strict off so it accepts schemas authored against more lenient specs (older drafts, schemas with OpenAPI-only extensions, hand-written shortcuts). The trade-off is that typos in keyword names go undetected — `requried` instead of `required` silently does nothing. For authoring new schemas, run them through Ajv strict mode in your code separately.

Related concepts

JSON Schema is a vocabulary for describing the shape of JSON data — what fields must be present, what types they take, what values are allowed, how arrays look. The specification draft is *paused at* Draft 2020-12 as of 2026; the standardization track moved to IETF in 2022 and produced the 2020-12 draft as its current target, but no formal RFC yet. Despite that, most ecosystems (Ajv, jsonschema for Python, Swagger / OpenAPI 3.1, AWS API Gateway, JSON Forms) implement 2020-12 or its predecessor 2019-09. Older code may still reference Draft 07 (the previous LTS-like checkpoint from 2018).

The vocabulary covers four broad areas. **Structure**: `type`, `properties`, `required`, `items`, `additionalProperties`, `patternProperties`. **Constraints**: `minimum`, `maximum`, `minLength`, `maxLength`, `pattern`, `uniqueItems`, `enum`, `const`. **Composition**: `allOf` (must match all), `anyOf` (at least one), `oneOf` (exactly one), `not`, `if / then / else`. **Reuse**: `$defs` for named subschemas, `$ref` to reference them by JSON Pointer or absolute URI, `$anchor` for stable named targets. Most production schemas use 5–10 keywords total; the long tail exists mainly for the spec's self-description and edge cases.

Three adjacent ideas sit nearby. **OpenAPI** (formerly Swagger) wraps JSON Schema in an HTTP API description format; 3.1 fully aligns, 3.0 has a forked subset. **TypeScript types** cover similar ground at compile time, but the runtime side needs a bridge (`zod`, `io-ts`, `runtypes`, `valibot`, `typia`) because TypeScript erases at compile. **Protocol Buffers** and **GraphQL SDL** solve the same problem with a different syntax — schema + binary wire format for protobuf, schema + query language for GraphQL. JSON Schema wins where you already have JSON and want to layer validation onto it without rewriting your transport.

Related articles

Related tools