Json Schema Reference

Comprehensive reference for json schema reference covering essential concepts, practical examples, and production best practices.

Json Schema is a declarative format for describing the structure, constraints, and semantics of JSON data. Use it when validating input, documenting APIs, or enforcing consistency across services. It is the backbone of reliable JSON interchange in distributed systems.

Core Structure and Schema Basics

A JSON Schema defines a JSON object with a root set of keys. The most essential keys are type, properties, and required.

{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "name": { "type": "string", "minLength": 1 },
    "active": { "type": "boolean" }
  },
  "required": ["id", "name"]
}

Schema Validation Workflow

To validate a JSON document against a schema:

jsonschema -s schema.json -d data.json

This command returns exit code 0 on success, 1 on failure. On failure, it prints a detailed error:

{
  "error": "Invalid JSON",
  "schema": { "file": "schema.json" },
  "instance": { "file": "data.json" },
  "messages": [
    "instance.id: type mismatch; expected integer but found string",
    "instance.name: missing required property",
    "instance.active: missing required property"
  ]
}

The jsonschema tool (from jsonschema Python package) is the most reliable CLI validator. It supports:

Validating Complex Types

Arrays

Arrays are validated with items, minItems, maxItems, and uniqueItems.

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "label": { "type": "string" },
      "value": { "type": "number" }
    },
    "required": ["label", "value"]
  },
  "minItems": 1,
  "uniqueItems": true
}

Nested Objects and References

Use $ref to reuse schemas across documents.

{
  "$id": "https://example.com/schemas/user.json",
  "type": "object",
  "properties": {
    "profile": { "$ref": "https://example.com/schemas/person.json" },
    "settings": { "$ref": "#/definitions/Preferences" }
  },
  "definitions": {
    "Preferences": {
      "type": "object",
      "properties": {
        "theme": { "type": "string", "enum": ["light", "dark"] },
        "notifications": { "type": "boolean" }
      }
    }
  }
}

Conditional Validation with oneOf, anyOf, allOf

Use oneOf for mutually exclusive structures:

{
  "oneOf": [
    {
      "type": "object",
      "properties": { "type": { "const": "user" } },
      "required": ["type"]
    },
    {
      "type": "object",
      "properties": { "type": { "const": "admin" } },
      "required": ["type"]
    }
  ]
}

allOf is critical for composing schemas:

{
  "allOf": [
    { "$ref": "base-entity.json" },
    { "$ref": "user-roles.json" },
    { "properties": { "metadata": { "type": "object" } } }
  ]
}

Advanced Features and Common Pitfalls

Format Validation

Use format to validate string, date, or URI formats:

{
  "type": "string",
  "format": "email"
}

Common formats: date-time, time, date, uri, email, hostname, ipv4, ipv6, uuid.

Custom Formats

Register custom formats via format with a function or external validation:

{
  "type": "string",
  "format": "slug",
  "pattern": "^[a-z0-9-]+$"
}

Default Values and Property Inheritance

Defaults are applied during validation but not required to be present:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "active": {
      "type": "boolean",
      "default": true
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "default": "2023-01-01T00:00:00Z"
    }
  },
  "required": ["name"]
}

Multiple Validation Errors

By default, validation collects all errors. Use allErrors: true to enable full reporting:

{
  "type": "object",
  "properties": {
    "name": { "type": "string", "minLength": 3 },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name"],
  "allErrors": true
}

Validation Fails Silently on Unknown Keys

When additionalProperties is true, unknown keys are allowed. When additionalProperties is false, unknown keys fail validation.

{
  "type": "object",
  "properties": { "name": { "type": "string" } },
  "additionalProperties": false
}

Misleading nullable and type

nullable is a top-level feature, but it does not imply type:

{
  "type": "string",
  "nullable": true
}

Use type: ["string", "null"] when you need to validate the string with format, pattern, or enum:

{
  "type": ["string", "null"],
  "format": "email",
  "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}

Schema Versioning and $id

Use $id to version and reference schemas:

{
  "$id": "https://example.com/schemas/v1/user.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "User",
  "description": "A user account with profile and preferences."
}

Schema Resolution and Dependencies

When using $ref, resolution follows these rules:

When a schema is included via $ref, its properties and required are merged with the current schema.

Error Messages and Customization

Use errorMessages to provide human-readable error feedback:

{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "errorMessages": {
        "format": "Invalid email format. Must be a valid email address.",
        "required": "Email is required."
      }
    }
  },
  "required": ["email"],
  "errorMessages": {
    "required": "All required fields must be present."
  }
}

Common Failure Modes and Sharp Edges

required on null fields

required: ["name"] fails if name is null, even if name exists.

{ "name": null }
{
  "type": "object",
  "properties": {
    "name": {
      "type": ["string", "null"],
      "nullable": true
    }
  },
  "required": ["name"]
}

items vs items array

uniqueItems and minItems with allOf

When combining allOf, uniqueItems applies to the merged schema:

{
  "allOf": [
    { "items": { "type": "string" } },
    { "minItems": 2 },
    { "uniqueItems": true }
  ]
}

format on arrays

format: "date-time" on an array applies format to each element:

{
  "type": "array",
  "items": { "type": "string", "format": "date-time" }
}

const vs enum

Use const for exact values; use enum when you need flexibility.

oneOf with discriminator

Use discriminator to select schema branches:

{
  "oneOf": [
    { "$ref": "#/definitions/User" },
    { "$ref": "#/definitions/Admin" }
  ],
  "discriminator": {
    "propertyName": "role",
    "mapping": {
      "user": "#/definitions/User",
      "admin": "#/definitions/Admin"
    }
  }
}

Summary of Key Flags and Options

Flag/KeyEffect
type: "object"Validates a JSON object
propertiesDefines key-value structure
requiredEnsures keys exist and are non-null
additionalProperties: falseFails on unknown keys
allErrors: trueCollects all validation errors
format: "email"Validates email format
nullable: trueAllows null value
enum: [...]Allows one of a set of values
const: valueValidates exact value
oneOf, anyOf, allOfConditional validation
$refReuse and reference schemas
definitionsLocal schema components
errorMessagesCustom error text per validation step

Use jsonschema CLI with --draft-07 --strict --verbose in production pipelines. Always validate schema against itself using jsonschema -s schema.json -d schema.json.

This page was rewritten on 10 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.