JSON Schema Cheat Sheet
Quick reference for JSON Schema: core keywords, validation rules, arrays, nested objects, references, and common patterns.
Data Formats
json
json-schema
validation
JSON Schema describes the shape of JSON data and validates whether a document matches. Draft 2020-12 is the current standard; many tools still default to draft-07. A schema is itself valid JSON.
Core Keywords
Table
| Keyword | Purpose | Example |
|---|---|---|
$schema | Which draft the schema follows | "$schema": "https://json-schema.org/draft/2020-12/schema" |
$id | Canonical URI identifier for the schema | "$id": "https://example.com/pet.schema.json" |
$ref | Reference another schema or subschema | "$ref": "#/definitions/name" |
type | Expected type(s) | "type": "string" or ["string", "null"] |
title / description | Documentation | "description": "The pet's name" |
default | Default value (informational) | "default": "Fido" |
Type-Specific Keywords
Table
| Type | Keywords |
|---|---|
string | minLength, maxLength, pattern, format |
number / integer | minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf |
array | items, prefixItems, minItems, maxItems, uniqueItems, contains |
object | properties, required, additionalProperties, minProperties, maxProperties, propertyNames, patternProperties |
A Validation Example
json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/order.schema.json",
"type": "object",
"required": ["id", "customer", "items"],
"properties": {
"id": { "type": "string", "minLength": 1 },
"customer": {
"type": "object",
"required": ["email"],
"properties": {
"email": { "type": "string", "format": "email" },
"name": { "type": "string" }
},
"additionalProperties": false
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["sku", "qty"],
"properties": {
"sku": { "type": "string" },
"qty": {
"type": "integer",
"minimum": 1,
"exclusiveMaximum": 1000
}
}
}
}
}
}
Arrays: items vs prefixItems
items validates every element against one schema. prefixItems (draft 2020-12; called items as an array in draft-07) validates positional tuples.
json
{
"type": "array",
"prefixItems": [
{ "type": "string" },
{ "type": "integer" }
],
"items": false,
"minItems": 2
}
Combining Keywords
Table
| Keyword | Behavior | Example |
|---|---|---|
allOf | Every subschema must pass | "allOf": [{ "type": "object" }, { "required": ["id"] }] |
anyOf | At least one subschema passes | "anyOf": [{ "type": "string" }, { "type": "number" }] |
oneOf | Exactly one subschema passes | "oneOf": [{ "required": ["car"] }, { "required": ["boat"] }] |
not | The subschema must fail | "not": { "type": "null" } |
$ref and Definitions
$ref keeps schemas DRY. Relative refs resolve against $id when one is set.
json
{
"$defs": {
"address": {
"type": "object",
"required": ["city"],
"properties": {
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^[0-9]{5}$" }
}
}
},
"type": "object",
"properties": {
"billing": { "$ref": "#/$defs/address" },
"shipping": { "$ref": "#/$defs/address" }
}
}
Common Pitfalls
Table
| Pitfall | Fix |
|---|---|
Forgetting additionalProperties: false | Allows typos to pass silently; set it where strictness matters. |
exclusiveMinimum: 1 at top level (draft-07) | Draft-07 used a boolean form; draft-06+ uses the numeric form shown above. |
Using required inside properties | required is a sibling of properties, not a child. |
format not enforced by default | format is annotation-only unless the validator opts in; test with a strict validator. |
$ref into a non-existent path | Reference errors fail the whole schema; validate the schema first. |