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 errorsPython (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
| Format | Description |
|---|---|
| date-time | ISO 8601 date-time |
| date | ISO 8601 date |
| time | ISO 8601 time |
| Email address | |
| hostname | Internet hostname |
| ipv4 | IPv4 address |
| ipv6 | IPv6 address |
| uri | Uniform Resource Identifier |
| uuid | Universally Unique Identifier |
Best Practices
- Start Simple: Begin with basic validation, add complexity as needed
- Use $id and $schema: Make schemas referenceable and versioned
- Add Descriptions: Document your schema for future developers
- Set Defaults: Provide sensible default values
- Be Specific: Use minLength, maxLength, format, pattern
- Reuse Schemas: Use $ref to reference common definitions
- Version Your Schemas: Include version in $id
- Test Your Schemas: Validate both valid and invalid data
Tools for Working with JSON Schema
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.