JSON Schema Guide: Validate and Document JSON Structures

10 min readJSON & Data

JSON Schema is a powerful specification for defining the structure and validation rules for JSON data. Whether you are building APIs, creating configuration files, or documenting data formats, JSON Schema provides a standardized way to describe what valid JSON should look like. This guide covers the fundamentals of JSON Schema with practical examples.

What is JSON Schema?

JSON Schema is a JSON document that describes the structure and constraints of other JSON documents. Think of it as a blueprint or contract for your data. It specifies:

  • What fields must exist (required properties)
  • What types each field should be (string, number, object, array)
  • What values are allowed (enums, patterns, ranges)
  • How nested objects and arrays should be structured

Basic JSON Schema Structure

Every JSON Schema starts with a root object that identifies it as a schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://bytejson.com/schemas/user.json",
  "title": "User",
  "description": "A user account object",
  "type": "object"
}
$schema

The JSON Schema version being used

$id

Unique identifier for the schema

title

Human-readable title

type

The root data type

Defining Properties

The properties keyword defines the fields in your object:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "active": {
      "type": "boolean"
    }
  }
}

Required Fields

Use the required array to specify which properties must be present:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "email": { "type": "string", "format": "email" },
    "phone": { "type": "string" }
  },
  "required": ["name", "email"]
}

In this example, name and email are required, while phone is optional.

String Constraints

JSON Schema provides several ways to constrain strings:

{
  "type": "string",
  "minLength": 5,
  "maxLength": 50,
  "pattern": "^\w+$",
  "format": "email"
}
minLength/maxLength

Character count limits

pattern

Regex pattern for validation

format

Predefined formats: email, date, uri

enum

List of allowed values

Arrays in JSON Schema

Define array structure with items and size constraints:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id": { "type": "integer" },
      "name": { "type": "string" }
    },
    "required": ["id"]
  },
  "minItems": 1,
  "maxItems": 100
}

Nested Objects

Nest schemas to create complex structures:

{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "address": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "country": { "type": "string" }
          }
        }
      }
    }
  }
}

Complete Example: API User Schema

Here is a complete JSON Schema for a typical user API response:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "user-schema",
  "title": "User",
  "description": "User object for API responses",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "Unique identifier"
    },
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 30,
      "pattern": "^[a-zA-Z0-9_]+$"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "role": {
      "type": "string",
      "enum": ["admin", "user", "guest"]
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" }
    }
  },
  "required": ["id", "username", "email"]
}

Best Practices

  • Always include $schema to specify the version
  • Add description to document each property
  • Use formats for common patterns (email, date, uri)
  • Keep schemas modular with references ($ref)
  • Validate during development, not just production

Related Tools