← Back to JSON Tools

JSON Schema Tutorial 2025

Learn JSON Schema Validation Step-by-Step with Practical Examples

Master JSON Schema validation with our comprehensive guide. Learn to create schemas, validate data, and implement advanced patterns for robust JSON APIs and applications.

📚 30 min read 🛡️ Validation Focus ⚡ Practical Examples 👨‍💻 Developer Guide

Written by the Better JSON Viewer Team — trusted source for JSON formatting and validation tutorials.

📋 Table of Contents

🤔 What is JSON Schema? — Understanding JSON Schema Fundamentals

JSON Schema is a declarative language for validating, documenting, and constraining JSON data. It provides a contract for your JSON data structure, ensuring consistency and enabling automatic validation.

🎯 Why Use JSON Schema?

  • Data Validation: Automatically validate API inputs and outputs
  • Documentation: Self-documenting data structures
  • Error Prevention: Catch data issues early in development
  • IDE Support: Enable autocomplete and validation in editors
  • Code Generation: Generate types and classes from schemas
Simple JSON Schema Example

JSON Data

{
  "name": "John Doe",
  "age": 30,
  "email": "john@example.com"
}

JSON Schema

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

🏗️ JSON Schema Basic Structure and Syntax Rules

Every JSON Schema starts with a basic structure that defines the schema version, type, and validation rules.

Essential Schema Keywords

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user-schema.json",
  "title": "User Schema",
  "description": "Schema for user data validation",
  "type": "object",
  "properties": {},
  "required": []
}

📋 Schema Keyword Explanation

  • $schema: Specifies the JSON Schema version (2020-12 is latest)
  • $id: Unique identifier for the schema (optional)
  • title & description: Human-readable documentation
  • type: The expected data type (object, array, string, etc.)
  • properties: Defines object properties and their schemas
  • required: Array of required property names

🎯 JSON Schema Data Types and Validation Rules

JSON Schema supports all JSON data types with specific validation keywords for each type.

string

String Validation

{
  "type": "string",
  "minLength": 1,
  "maxLength": 100,
  "pattern": "^[A-Za-z]+$"
}

Validates text data with length and pattern constraints.

number / integer

Number Validation

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "multipleOf": 0.5
}

Validates numeric data with range and divisibility rules.

boolean

Boolean Validation

{
  "type": "boolean"
}

Simple true/false validation. No additional constraints needed.

array

Array Validation

{
  "type": "array",
  "items": { "type": "string" },
  "minItems": 1,
  "uniqueItems": true
}

Validates arrays with item types, length, and uniqueness.

object

Object Validation

{
  "type": "object",
  "properties": {},
  "additionalProperties": false,
  "minProperties": 1
}

Validates objects with property schemas and constraints.

null

Null Validation

{
  "type": ["string", "null"]
}

Allows null values, often combined with other types.

⚠️ Type Validation Tips

  • Use integer instead of number when you need whole numbers
  • Combine types with arrays: ["string", "null"] for optional strings
  • Remember that JSON numbers include integers, floats, and scientific notation

🏢 Object Validation

Objects are the most complex JSON Schema type, supporting nested properties, pattern properties, and additional property constraints.

Basic Object Schema

User Profile Schema
{
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "minimum": 1,
      "description": "Unique user identifier"
    },
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 20,
      "pattern": "^[a-zA-Z0-9_]+$"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "profile": {
      "type": "object",
      "properties": {
        "firstName": { "type": "string" },
        "lastName": { "type": "string" },
        "age": { 
          "type": "integer", 
          "minimum": 13, 
          "maximum": 120 
        }
      },
      "required": ["firstName", "lastName"]
    }
  },
  "required": ["id", "username", "email"],
  "additionalProperties": false
}

Advanced Object Features

Pattern Properties

Validate objects with dynamic property names using regular expressions:

{
  "type": "object",
  "patternProperties": {
    "^[a-zA-Z_][a-zA-Z0-9_]*$": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

Property Dependencies

Require certain properties when others are present:

{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "credit_card": { "type": "string" },
    "billing_address": { "type": "string" }
  },
  "dependentRequired": {
    "credit_card": ["billing_address"]
  }
}

📊 JSON Schema Array Validation Examples and Patterns

Arrays in JSON Schema can be validated in multiple ways depending on whether all items should have the same schema (list validation) or specific positions have specific schemas (tuple validation).

List Validation (Homogeneous Arrays)

String Array Schema
{
  "type": "array",
  "items": {
    "type": "string",
    "minLength": 1
  },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true
}
✅ Valid: ["apple", "banana", "orange"]
❌ Invalid: ["apple", ""] (empty string violates minLength)

Tuple Validation (Heterogeneous Arrays)

Coordinate Tuple Schema
{
  "type": "array",
  "prefixItems": [
    { "type": "number", "description": "latitude" },
    { "type": "number", "description": "longitude" },
    { 
      "type": "string", 
      "description": "location name",
      "minLength": 1
    }
  ],
  "items": false,
  "minItems": 2,
  "maxItems": 3
}
✅ Valid: [40.7128, -74.0060, "New York City"]
❌ Invalid: ["40.7128", -74.0060] (first item should be number, not string)

Complex Array Examples

Array of Objects

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

Array with Contains Constraint

{
  "type": "array",
  "items": { "type": "string" },
  "contains": {
    "type": "string",
    "pattern": "^admin"
  },
  "minContains": 1,
  "maxContains": 3
}

🔤 String Patterns & Formats

String validation in JSON Schema is powerful, supporting regular expressions, predefined formats, and custom constraints.

Built-in String Formats

Email Format

{
  "type": "string",
  "format": "email"
}
✅ user@example.com
❌ invalid-email

URI Format

{
  "type": "string",
  "format": "uri"
}
✅ https://example.com
❌ not-a-uri

Date-Time Format

{
  "type": "string",
  "format": "date-time"
}
✅ 2025-01-14T10:30:00Z
❌ 2025-01-14

UUID Format

{
  "type": "string",
  "format": "uuid"
}
✅ 123e4567-e89b-12d3-a456-426614174000
❌ not-a-uuid

Custom String Patterns

Common Regex Patterns
// Phone Number (US)
{
  "type": "string",
  "pattern": "^\\+?1?[2-9]\\d{2}[2-9]\\d{2}\\d{4}$"
}

// Strong Password
{
  "type": "string",
  "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$",
  "minLength": 8
}

// Semantic Version
{
  "type": "string",
  "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
}

// Hex Color Code
{
  "type": "string",
  "pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
}

🚀 Advanced JSON Schema Features

Conditional Schemas (if/then/else)

{
  "type": "object",
  "properties": {
    "userType": { "enum": ["admin", "user"] },
    "permissions": { "type": "array" }
  },
  "if": {
    "properties": { "userType": { "const": "admin" } }
  },
  "then": {
    "required": ["permissions"]
  }
}

Schema Composition (allOf/anyOf/oneOf)

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "type": { "const": "email" },
        "address": { "format": "email" }
      }
    },
    {
      "type": "object",
      "properties": {
        "type": { "const": "sms" },
        "number": { "pattern": "^\\+[1-9]\\d{1,14}$" }
      }
    }
  ]
}

Schema References ($ref)

{
  "$defs": {
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      }
    }
  },
  "type": "object",
  "properties": {
    "home": { "$ref": "#/$defs/address" },
    "work": { "$ref": "#/$defs/address" }
  }
}

Enum & Const Values

{
  "type": "object",
  "properties": {
    "status": {
      "enum": ["active", "inactive", "pending"]
    },
    "version": {
      "const": "1.0"
    },
    "priority": {
      "enum": [1, 2, 3, 4, 5]
    }
  }
}

🌍 Real-World Schema Examples

REST API User Schema

Complete User API Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://api.example.com/schemas/user.json",
  "title": "User",
  "description": "A user in our system",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Unique identifier"
    },
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 30,
      "pattern": "^[a-zA-Z0-9_]+$"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "profile": {
      "type": "object",
      "properties": {
        "firstName": { "type": "string", "minLength": 1 },
        "lastName": { "type": "string", "minLength": 1 },
        "avatar": { "type": "string", "format": "uri" },
        "birthDate": { "type": "string", "format": "date" }
      },
      "required": ["firstName", "lastName"]
    },
    "roles": {
      "type": "array",
      "items": {
        "enum": ["admin", "user", "moderator", "guest"]
      },
      "uniqueItems": true,
      "minItems": 1
    },
    "preferences": {
      "type": "object",
      "properties": {
        "theme": { "enum": ["light", "dark", "auto"] },
        "language": { "type": "string", "pattern": "^[a-z]{2}(-[A-Z]{2})?$" },
        "notifications": {
          "type": "object",
          "properties": {
            "email": { "type": "boolean" },
            "push": { "type": "boolean" },
            "sms": { "type": "boolean" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "createdAt": { "type": "string", "format": "date-time" },
    "updatedAt": { "type": "string", "format": "date-time" },
    "isActive": { "type": "boolean" }
  },
  "required": ["id", "username", "email", "profile", "roles", "createdAt", "isActive"],
  "additionalProperties": false
}

E-commerce Product Schema

Product Catalog Schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "sku": { "type": "string", "pattern": "^[A-Z0-9]{3,20}$" },
    "name": { "type": "string", "minLength": 1, "maxLength": 200 },
    "description": { "type": "string", "maxLength": 2000 },
    "category": {
      "type": "object",
      "properties": {
        "primary": { "type": "string" },
        "secondary": { "type": "string" },
        "tags": {
          "type": "array",
          "items": { "type": "string" },
          "uniqueItems": true
        }
      },
      "required": ["primary"]
    },
    "pricing": {
      "type": "object",
      "properties": {
        "currency": { "type": "string", "pattern": "^[A-Z]{3}$" },
        "basePrice": { "type": "number", "minimum": 0 },
        "salePrice": { "type": "number", "minimum": 0 },
        "taxRate": { "type": "number", "minimum": 0, "maximum": 1 }
      },
      "required": ["currency", "basePrice"]
    },
    "variants": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "attributes": {
            "type": "object",
            "patternProperties": {
              ".*": { "type": "string" }
            }
          },
          "stock": { "type": "integer", "minimum": 0 }
        },
        "required": ["id", "stock"]
      }
    }
  },
  "required": ["sku", "name", "category", "pricing"]
}

🏆 JSON Schema Best Practices

🎯 Schema Design Guidelines

  • Start Simple: Begin with basic structure and add complexity gradually
  • Use Descriptive Names: Property names should be clear and self-documenting
  • Add Documentation: Include title and description for all schemas and properties
  • Version Your Schemas: Use $id with version numbers for schema evolution
  • Validate Examples: Always test your schemas with real data examples

🛡️ Validation Strategy

  • Fail Fast: Use required fields and strict constraints to catch errors early
  • Clear Error Messages: Write schemas that produce helpful validation errors
  • Performance Considerations: Avoid overly complex nested schemas for high-volume APIs
  • Security: Use additionalProperties: false to prevent data injection
  • Backward Compatibility: Plan for schema evolution without breaking existing data

Schema Organization & Reusability

// Good: Reusable definitions
{
  "$defs": {
    "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp"
    },
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Unique identifier"
    }
  },
  "type": "object",
  "properties": {
    "id": { "$ref": "#/$defs/id" },
    "createdAt": { "$ref": "#/$defs/timestamp" },
    "updatedAt": { "$ref": "#/$defs/timestamp" }
  }
}

⚠️ Common Schema Mistakes

  • Missing Required Fields: Not specifying which properties are mandatory
  • Overly Permissive: Using additionalProperties: true without constraints
  • Wrong Data Types: Using string for numbers or missing integer vs number distinction
  • Circular References: Creating schemas that reference themselves infinitely
  • No Validation Testing: Not testing schemas against actual data

Testing Your Schemas

// Test strategy for JSON Schema validation

1. Valid Data Tests
   - Test with minimal required data
   - Test with all optional fields populated
   - Test edge cases (empty arrays, null values)

2. Invalid Data Tests
   - Missing required fields
   - Wrong data types
   - Out-of-range values
   - Invalid formats

3. Performance Tests
   - Large datasets
   - Complex nested structures
   - High-frequency validation scenarios

🚀 Start Using JSON Schema Today

Try our JSON Schema validation tool to test your schemas against real data. Validate, debug, and perfect your JSON Schema implementations.

Try Schema Validator → JSON Validation Guide Security Best Practices

📚 Complete JSON Developer Guide Series

Master JSON development with our comprehensive tutorial collection

JSON Validation Tutorial
Learn JSON syntax validation
JSON Security Guide
Secure JSON processing practices
JSON Troubleshooting
Fix common JSON errors
JSON to CSV Converter
Convert JSON data formats

JSON Schema Resources

Schema Resources

  • JSON Schema Specification
  • Schema Validation Libraries
  • API Documentation Tools
  • Code Generation Tools

Advanced Topics

  • Schema Composition Patterns
  • Conditional Validation
  • Schema Migration Strategies
  • Performance Optimization

Complete guide to JSON Schema validation for modern web development.

Last updated: January 14, 2025 • © 2025 Better JSON Viewer