JSON & XML Tools
Tools Guides About Contact

JSON Schema validation: a practical guide

Catch invalid API payloads before they break your application

Updated: June 2026 · All guides

JSON is easy to produce and easy to get wrong. A missing field, a string where you expected a number, or an extra property can slip through code review and cause runtime errors hours later. JSON Schema is a declarative language for describing the shape of JSON documents. Validators compare a payload against that description and report every mismatch — before your application trusts the data.

Why validate at all?

Client-side validation in your app catches some problems, but schemas are especially useful when:

  • You consume third-party APIs and want to detect breaking changes early
  • You publish an API and need a contract both teams can agree on
  • You store configuration as JSON and want CI to reject invalid files
  • You debug webhook payloads where the sender sends inconsistent shapes

JSON Schema does not replace business-logic validation (e.g. “end date must be after start date”), but it eliminates an entire class of structural bugs cheaply.

A minimal schema example

Suppose your API returns user objects with an integer id, string name, and optional email:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "name": { "type": "string", "minLength": 1 },
    "email": { "type": "string", "format": "email" }
  },
  "additionalProperties": false
}

Setting additionalProperties to false rejects typos like "nmae" instead of silently ignoring them. The format keyword checks common patterns (email, date-time, uri) when your validator supports it.

Valid vs invalid payloads

This payload passes:

{ "id": 42, "name": "Ada Lovelace", "email": "ada@example.com" }

These fail, with clear error paths:

{ "id": "42", "name": "Ada" }
// → /id must be integer

{ "id": 1 }
// → must have required property 'name'

{ "id": 1, "name": "Ada", "role": "admin" }
// → must NOT have additional properties (role)

Common schema patterns

Arrays of objects

{
  "type": "array",
  "items": {
    "type": "object",
    "required": ["sku", "qty"],
    "properties": {
      "sku": { "type": "string" },
      "qty": { "type": "integer", "minimum": 0 }
    }
  },
  "minItems": 1
}

Enums and one-of

Use enum for fixed string sets ("status": { "enum": ["draft", "published"] }). Use oneOf when an object can match exactly one of several shapes — useful for polymorphic event payloads.

Nested definitions with $ref

Large schemas stay maintainable when you define reusable fragments under $defs and reference them. Draft 2020-12 uses $defs; older drafts used definitions.

Tip: Start strict (additionalProperties: false) and relax only when you have a documented reason. Loose schemas miss regressions; tight schemas force intentional API changes.

Validating in the browser (locally)

Our JSON Editor Pro includes JSON Schema validation powered by AJV. Paste your schema and sample JSON, switch to Validate mode, and read line-level errors in the panel. Because validation runs in your browser, sensitive API samples never leave your machine — important when debugging production payloads that contain PII.

Workflow for API teams

  1. Write or export a schema from your OpenAPI spec (components.schemas)
  2. Save example responses from staging and production
  3. Validate each example against the schema in JSON Editor Pro
  4. When validation fails after a deploy, use JSON Diff to compare old vs new responses
  5. Update the schema or fix the API, then re-validate

Frequent mistakes

  • Wrong draft URL — Match $schema to keywords your validator supports
  • Optional vs required — Omitting a key from required makes it optional even if documented otherwise
  • Integer vs number — JSON has no int type; use integer in schema, not number, when fractional values are invalid
  • Nullable fields — In draft 2020-12, use type: ["string", "null"] instead of legacy nullable: true
  • Empty strings vs missing keys — "" passes type: string but may fail minLength: 1; decide which you mean in API docs
  • Date formats — format: date-time expects ISO 8601; timestamps with space instead of T often fail

Real-world example: order payload

E-commerce APIs often return nested objects. Here is a schema fragment for an order list item — the kind of structure you might validate before feeding data into a dashboard:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["orderId", "status", "lines"],
  "properties": {
    "orderId": { "type": "string", "pattern": "^ORD-[0-9]{6}$" },
    "status": { "enum": ["pending", "shipped", "cancelled"] },
    "lines": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["sku", "quantity", "unitPrice"],
        "properties": {
          "sku": { "type": "string" },
          "quantity": { "type": "integer", "minimum": 1 },
          "unitPrice": { "type": "number", "minimum": 0 }
        }
      }
    }
  },
  "additionalProperties": false
}

Paste this schema into JSON Editor Pro, then paste a sample API response. If a backend deploy changes status to "processing" without updating the enum, validation fails immediately — often faster than waiting for a UI bug report.

JSON Schema and OpenAPI

If your team publishes OpenAPI 3 specs, schemas under components.schemas are JSON Schema objects (with minor dialect differences). Export the relevant schema — e.g. UserResponse — and validate live traffic against it. When OpenAPI and reality diverge, either the spec is stale or the API regressed; schema validation tells you which samples fail so you can diff responses next.

Reusing definitions with $ref

Split large schemas to avoid copy-paste drift:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "address": {
      "type": "object",
      "required": ["city", "country"],
      "properties": {
        "city": { "type": "string" },
        "country": { "type": "string", "minLength": 2, "maxLength": 2 }
      }
    }
  },
  "type": "object",
  "properties": {
    "billing": { "$ref": "#/$defs/address" },
    "shipping": { "$ref": "#/$defs/address" }
  }
}

Update address once; both billing and shipping stay in sync. Draft 2019-09 and 2020-12 use $defs; older drafts used definitions — check your validator (AJV supports modern drafts).

Where validation fits in your pipeline

  • Local debugging — paste failing webhook body, fix schema or report upstream bug
  • CI/CD — validate fixture JSON files in repo against checked-in schemas
  • Contract tests — combine schema check with HTTP status and headers
  • Documentation — schema is executable docs; invalid examples fail validation in PR review

FAQ

Does JSON Schema validate business rules?

Only structurally. It can enforce types, ranges, patterns, and required fields — not rules like “discount cannot exceed subtotal.” Use application code for that, or combine schema validation with custom checks.

Which draft should I use?

Draft 2020-12 for new projects. Match the $schema URL to what your toolchain (AJV, OpenAPI generator, VS Code extension) supports.

Can I validate YAML configs with JSON Schema?

Parse YAML into JSON first (e.g. with yq or your CI toolchain), then validate the JSON against your schema. Be aware YAML-specific quirks (unquoted yes/no) may change values during conversion — see our JSON vs YAML guide.

Related tools & guides

  • JSON Editor Pro — schema validation built in
  • How to compare two JSON API responses
  • Editing JSON safely in the browser
← All guides Next: Compare API responses →
Home Privacy Terms About Guides For IT Contact Anita Kumawat · Tvishi Tech Services · webtoolkit.in