JSON Schema Tutorial: Validate JSON with Examples
JSON Schema lets you describe the structure of a JSON document and validate data against it. It's used for API contract testing, form validation, configuration file validation, and auto-generating TypeScript types. This tutorial covers the essentials with real examples.
What is JSON Schema?
JSON Schema is a vocabulary for annotating and validating JSON data. A schema is itself a JSON document that describes what valid data looks like: which fields are required, what types they must be, and what constraints they must satisfy.
// A simple schema for a user object
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": { "type": "integer" },
"email": { "type": "string", "format": "email" },
"name": { "type": "string" }
}
}
// Valid data:
{ "id": 1, "email": "alice@example.com", "name": "Alice" }
{ "id": 2, "email": "bob@example.com" }
// Invalid data:
{ "email": "alice@example.com" } // missing required "id"
{ "id": "one", "email": "a@b.com" } // id must be integerCore keywords
type
Specifies the expected JSON type. Valid values: string, number, integer, boolean, array, object, null.
{ "type": "string" } // validates: "hello"
{ "type": "integer" } // validates: 42, not 3.14
{ "type": "number" } // validates: 42, 3.14
{ "type": ["string", "null"] } // validates: "hello" or nullproperties and required
properties defines a schema for each key. required lists keys that must be present. A key in properties but not in requiredis optional.
{
"type": "object",
"required": ["title", "price"],
"properties": {
"title": { "type": "string" },
"price": { "type": "number", "minimum": 0 },
"description": { "type": "string" } // optional
}
}String constraints
{
"type": "string",
"minLength": 1, // at least 1 character
"maxLength": 100, // at most 100 characters
"pattern": "^[a-z]+$" // must match regex (lowercase letters only)
}Number constraints
{
"type": "number",
"minimum": 0, // >= 0
"maximum": 100, // <= 100
"exclusiveMinimum": 0, // > 0 (draft-07 style)
"multipleOf": 0.5 // must be a multiple of 0.5
}enum
Restricts a value to a fixed set of allowed values.
{ "enum": ["pending", "active", "suspended", "deleted"] }
// Also works for mixed types:
{ "enum": [1, "one", null, true] }format
Provides semantic validation hints. Validators may or may not enforce format checks — it depends on the implementation.
{ "type": "string", "format": "email" }
{ "type": "string", "format": "date" } // "2024-01-15"
{ "type": "string", "format": "date-time" } // "2024-01-15T10:30:00Z"
{ "type": "string", "format": "uri" }
{ "type": "string", "format": "uuid" }Array validation
{
"type": "array",
"items": { "type": "string" }, // all items must be strings
"minItems": 1, // at least one item
"maxItems": 10, // at most ten items
"uniqueItems": true // no duplicate values
}Composition keywords
allOf, anyOf, oneOf
// allOf — must satisfy ALL sub-schemas
{
"allOf": [
{ "type": "object" },
{ "required": ["name"] }
]
}
// anyOf — must satisfy AT LEAST ONE sub-schema
{
"anyOf": [
{ "type": "string" },
{ "type": "number" }
]
}
// oneOf — must satisfy EXACTLY ONE sub-schema
{
"oneOf": [
{ "type": "string", "maxLength": 5 },
{ "type": "string", "minLength": 10 }
]
}not
// Must NOT be a string
{ "not": { "type": "string" } }$ref and $defs
Use $defs to define reusable sub-schemas and reference them with $ref:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"billing": { "$ref": "#/$defs/address" },
"shipping": { "$ref": "#/$defs/address" }
},
"$defs": {
"address": {
"type": "object",
"required": ["street", "city"],
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string" }
}
}
}
}Complete annotated example
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Product",
"type": "object",
"required": ["id", "name", "price", "category"],
"additionalProperties": false,
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": 0
},
"category": {
"type": "string",
"enum": ["electronics", "books", "clothing", "food"]
},
"tags": {
"type": "array",
"items": { "type": "string", "minLength": 1 },
"uniqueItems": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}Draft versions
JSON Schema has multiple published drafts: draft-04, draft-06, draft-07, draft 2019-09, draft 2020-12. The most widely supported in libraries and tooling is draft-07. When writing schemas, always declare the version with $schema so validators know which spec to use.
Validate JSON against a schema
Paste your JSON and schema into Jsonic's JSON Schema Validator to check for errors instantly. Runs in your browser — nothing is uploaded.
Open JSON Schema Validator