NV ToolkitFormat · Validate · Convert
Tutorial

JSON Schema Tutorial: Contracts for Your JSON

JSON tells you what the data IS; JSON Schema tells you what the data is ALLOWED to be. It's the contract layer — machine-checkable rules that catch the missing field and the string-where-a-number-belongs before they reach production.

In short

JSON Schema is a JSON-based contract language that describes what a JSON document is allowed to contain: type constrains value kinds, properties defines an object's fields, required lists mandatory fields, and additionalProperties: false closes the object to surprises. It composes recursively for nested objects and arrays, and tools can infer a draft schema automatically from a sample payload.

By NaveenKumar T · Software engineer · builds and maintains NV Toolkit Published 2026-06-04 2 min read

Your first schema

A schema is itself JSON: it describes the shape a document must have. The core keywords cover 90% of real usage — type constrains the kind of value, properties describes an object's fields, required lists which fields must exist, and additionalProperties: false closes the object to surprises.

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

Nesting and arrays

Schemas compose exactly like the data they describe: a property's schema can be a full object schema, and arrays take an items schema applied to every element — with minItems/maxItems and uniqueItems for the list itself. This recursive composition is the whole mental model; once it clicks, any payload's schema writes itself.

json
{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "sku":   { "type": "string", "pattern": "^[A-Z]{2}-\\d+$" },
          "qty":   { "type": "integer", "minimum": 1 },
          "price": { "type": "number", "exclusiveMinimum": 0 }
        },
        "required": ["sku", "qty", "price"]
      }
    }
  }
}

The keywords you'll actually use

Beyond the basics: enum locks a value to a fixed set ("status": {"enum": ["active","paused"]}); pattern applies a regex to strings; format adds semantic checks (email, uri, date-time, uuid) — validators treat it as annotation or assertion depending on configuration; oneOf/anyOf express alternatives (a payment is card OR bank transfer); $ref reuses definitions so the Address schema is written once. Resist the deep end on day one — type, properties, required, items, and enum carry most production schemas.

KeywordPurposeExample
typeConstrains the value's kind"type": "string"
requiredLists fields that must be present"required": ["name", "email"]
enumLocks a value to a fixed set"enum": ["active", "paused"]
patternApplies a regex to strings"pattern": "^[A-Z]{2}-\\d+$"
formatAdds semantic checks"format": "email"
$refReuses a schema definition"$ref": "#/definitions/Address"

Don't write schemas from scratch — generate them

The fastest path from payload to contract is inference: paste a representative sample into our JSON to JSON Schema generator and get a draft schema with types and structure already filled in. Then harden it by hand — tighten required (generators can only guess from presence), add enums, ranges and formats the sample couldn't express. Wire the result into CI (ajv in JS, jsonschema in Python) or use it for editor autocomplete via $schema, and your API contract enforces itself from then on. Before that, check a few real payloads against the finished schema with our JSON Validator.

How this was tested: Syntax examples were validated with the site's own parser (JSON.parse) and checked against the 2020-12 meta-schema on 2026-09-10.

Sources

  1. JSON Schema Specification
  2. Understanding JSON Schema
  3. RFC 8259 — The JSON Data Interchange Format

Frequently asked questions

Where is JSON Schema actually used?

Everywhere contracts matter: OpenAPI request/response definitions are JSON Schema, editors use it for config autocomplete and inline validation (that's what a $schema key in tsconfig-style files does), CI pipelines validate fixtures against it, and form generators build UIs straight from it.

Is the generated schema from a sample production-ready?

It's a strong draft, not a contract: a sample shows what was present, not what's mandatory or what ranges apply. Review required, add constraints, and feed multiple representative samples for tighter inference — then it's production-ready.

Which draft of JSON Schema should I use?

2020-12 for new work — it's what current OpenAPI (3.1) and modern validators target. If a tool in your chain only speaks draft-07 (still common), stay consistent across the chain; mixing drafts is where mysterious validation differences come from.

Paste a real payload into JSON to JSON Schema — get the inferred contract in seconds, then harden it by hand.

Generate a schema

Keep working

Related tools