JSON Schema: Complete Guide & When to Use It

Master JSON Schema for robust data validation and documentation

Last updated: January 21, 2026 • 11 min read

What is JSON Schema?

JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. Think of it as a contract that your JSON data must follow - defining structure, data types, constraints, and documentation.

Why Use JSON Schema?

  • Validation: Ensure data meets requirements before processing
  • Documentation: Self-documenting API contracts
  • Code Generation: Auto-generate TypeScript interfaces, Go structs, etc.
  • IDE Support: Auto-completion and validation in editors
  • Testing: Verify API responses match expected format

Basic 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",
      "minLength": 1,
      "maxLength": 100
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "email": {
      "type": "string",
      "format": "email"
    }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

JSON Schema Data Types

1. String

{
  "type": "string",
  "minLength": 1,
  "maxLength": 100,
  "pattern": "^[A-Za-z]+$",  // Only letters
  "format": "email"  // Built-in format validation
}

2. Number/Integer

{
  "type": "number",
  "minimum": 0,
  "maximum": 100,
  "exclusiveMinimum": 0,  // Greater than 0, not equal
  "multipleOf": 0.5  // Must be divisible by 0.5
}

3. Boolean

{
  "type": "boolean"
}

4. Array

{
  "type": "array",
  "items": {
    "type": "string"
  },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true  // No duplicates
}

5. Object

{
  "type": "object",
  "properties": {
    "street": { "type": "string" },
    "city": { "type": "string" }
  },
  "required": ["street", "city"],
  "additionalProperties": false
}

6. Null

{
  "type": ["string", "null"]  // Can be string or null
}

Advanced JSON Schema Features

1. Enum (Allowed Values)

{
  "type": "string",
  "enum": ["admin", "user", "guest"]  // Must be one of these
}

2. Const (Exact Value)

{
  "const": "active"  // Must be exactly "active"
}

3. AnyOf (Multiple Valid Schemas)

{
  "anyOf": [
    { "type": "string" },
    { "type": "number" }
  ]  // Can be string OR number
}

4. AllOf (Combine Schemas)

{
  "allOf": [
    {
      "type": "object",
      "properties": {
        "name": { "type": "string" }
      }
    },
    {
      "properties": {
        "age": { "type": "number" }
      }
    }
  ]  // Must satisfy BOTH schemas
}

5. Conditional Validation (If/Then/Else)

{
  "type": "object",
  "properties": {
    "country": { "type": "string" },
    "postalCode": { "type": "string" }
  },
  "if": {
    "properties": { "country": { "const": "USA" } }
  },
  "then": {
    "properties": {
      "postalCode": { "pattern": "^\\d{5}$" }  // 5 digits for USA
    }
  },
  "else": {
    "properties": {
      "postalCode": { "type": "string" }  // Any string otherwise
    }
  }
}

Real-World Example: User Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/user.json",
  "title": "User",
  "description": "A user in our system",
  "type": "object",
  "properties": {
    "id": {
      "description": "Unique user identifier",
      "type": "integer",
      "minimum": 1
    },
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 20,
      "pattern": "^[a-zA-Z0-9_]+$"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "role": {
      "type": "string",
      "enum": ["admin", "moderator", "user"],
      "default": "user"
    },
    "isActive": {
      "type": "boolean",
      "default": true
    },
    "profile": {
      "type": "object",
      "properties": {
        "firstName": { "type": "string" },
        "lastName": { "type": "string" },
        "bio": { 
          "type": "string",
          "maxLength": 500
        },
        "avatarUrl": {
          "type": "string",
          "format": "uri"
        }
      },
      "required": ["firstName", "lastName"]
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "uniqueItems": true,
      "maxItems": 10
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  },
  "required": ["id", "username", "email"],
  "additionalProperties": false
}

Using JSON Schema in Code

JavaScript/Node.js (Using Ajv)

const Ajv = require('ajv');
const ajv = new Ajv();

const schema = {
  type: 'object',
  properties: {
    name: { type: 'string' },
    age: { type: 'number', minimum: 0 }
  },
  required: ['name'],
  additionalProperties: false
};

const validate = ajv.compile(schema);

// Valid data
const data1 = { name: 'John', age: 30 };
console.log(validate(data1));  // true

// Invalid data
const data2 = { name: 'John', age: -5 };
console.log(validate(data2));  // false
console.log(validate.errors);  // Shows validation errors

Python (Using jsonschema)

import jsonschema
from jsonschema import validate

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "number", "minimum": 0}
    },
    "required": ["name"]
}

# Valid data
data = {"name": "John", "age": 30}
try:
    validate(instance=data, schema=schema)
    print("Valid!")
except jsonschema.exceptions.ValidationError as e:
    print(f"Invalid: {e.message}")

When to Use JSON Schema

✅ Use JSON Schema When:

  • Building APIs: Validate request/response bodies
  • Configuration Files: Ensure config is correct
  • Data Import: Validate before processing
  • Form Validation: Generate forms from schemas
  • Documentation: Self-documenting data structures
  • Testing: Verify API contracts
  • Code Generation: Generate types/models

❌ Don't Use JSON Schema When:

  • Data structure is trivial (e.g., simple key-value pairs)
  • Performance is absolutely critical (adds overhead)
  • Data structure changes frequently (schema maintenance burden)
  • Team unfamiliar with it (steep learning curve)

Common Formats

FormatDescription
date-timeISO 8601 date-time
dateISO 8601 date
timeISO 8601 time
emailEmail address
hostnameInternet hostname
ipv4IPv4 address
ipv6IPv6 address
uriUniform Resource Identifier
uuidUniversally Unique Identifier

Best Practices

  1. Start Simple: Begin with basic validation, add complexity as needed
  2. Use $id and $schema: Make schemas referenceable and versioned
  3. Add Descriptions: Document your schema for future developers
  4. Set Defaults: Provide sensible default values
  5. Be Specific: Use minLength, maxLength, format, pattern
  6. Reuse Schemas: Use $ref to reference common definitions
  7. Version Your Schemas: Include version in $id
  8. Test Your Schemas: Validate both valid and invalid data

Tools for Working with JSON Schema

📋 JSON Schema Validator

Validate JSON against a schema

Validate Schema →

🔍 JSON Validator

Validate JSON syntax first

Validate JSON →

Conclusion

JSON Schema is a powerful tool for ensuring data quality, documenting APIs, and generating code. While it adds some complexity, the benefits in validation, documentation, and error prevention make it invaluable for production applications dealing with structured data.

Validate with JSON Schema

Try validating your JSON against a schema right now!

Validate with Schema →