JSON Schema Cheat Sheet
A reference for defining and validating JSON document structure using JSON Schema keywords, types, and constraints.
Basic Schema Structure
A minimal object schema with type and required fields.
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Person", "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer", "minimum": 0 }, "email": { "type": "string", "format": "email" } }, "required": ["name", "age"], "additionalProperties": false}
String & Number Constraints
Common validation keywords for primitive types.
{ "username": { "type": "string", "minLength": 3, "maxLength": 20, "pattern": "^[a-zA-Z0-9_]+$" }, "price": { "type": "number", "minimum": 0, "exclusiveMaximum": 10000, "multipleOf": 0.01 }, "status": { "type": "string", "enum": ["active", "inactive", "pending"] }}
Arrays & Composition
Array validation and combining schemas.
{ "tags": { "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }, "contact": { "oneOf": [ { "type": "string", "format": "email" }, { "type": "string", "format": "uri" } ] }, "discountedPrice": { "allOf": [ { "type": "number" }, { "minimum": 0 } ] }}
Key Keywords Reference
Frequently used JSON Schema keywords and what they do.
- type- Restricts value to one of: string, number, integer, boolean, object, array, null
- required- Array of property names that must be present on an object
- enum- Value must exactly match one of the listed values
- $ref- References another schema, e.g. `#/definitions/Address` or a `$defs` entry
- anyOf / oneOf / allOf- Value must match at least one, exactly one, or all listed subschemas
- additionalProperties- `false` disallows properties not listed in `properties`
- format- Semantic hint like `date-time`, `email`, `uri` (validated by some validators, advisory in others)
Conditional Validation (if/then/else)
Apply different constraints depending on another field's value, useful for polymorphic payloads.
{ "type": "object", "properties": { "paymentType": { "enum": ["card", "bank"] } }, "if": { "properties": { "paymentType": { "const": "card" } } }, "then": { "required": ["cardNumber", "cvv"] }, "else": { "required": ["accountNumber", "routingNumber"] }}
$defs, $ref & Recursive Schemas
Reusable subschemas and self-referencing structures for tree-shaped data like comment threads.
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://example.com/comment.schema.json", "title": "Comment", "type": "object", "properties": { "text": { "type": "string" }, "replies": { "type": "array", "items": { "$ref": "#" } } }, "required": ["text"], "$defs": { "author": { "type": "object", "properties": { "name": { "type": "string" } } } }}
patternProperties & dependentRequired
Validate dynamically-named keys and express cross-field requirements without if/then.
{ "type": "object", "patternProperties": { "^env_[A-Z_]+$": { "type": "string" } }, "additionalProperties": false, "dependentRequired": { "creditCard": ["billingAddress"] }, "dependentSchemas": { "isGift": { "required": ["giftMessage"] } }}
unevaluatedProperties with allOf
Closes the schema to extra properties even when the object is composed from multiple allOf branches, which additionalProperties alone can't do.
{ "allOf": [ { "type": "object", "properties": { "id": { "type": "string" } } }, { "type": "object", "properties": { "name": { "type": "string" } } } ], "unevaluatedProperties": false}// { "id": "1", "name": "Ada" } -> valid// { "id": "1", "name": "Ada", "x": 1 } -> invalid, "x" not evaluated by either branch
Advanced Keyword Reference
Less common keywords that matter once schemas grow beyond simple validation.
- $anchor / $dynamicAnchor- Named fragments referenced via `#anchorName` instead of a JSON Pointer path, used for recursive/extensible base schemas
- $dynamicRef- Resolves against the nearest matching `$dynamicAnchor` at evaluation time, enabling schema extension/override patterns
- propertyNames- Applies a schema to every key name in an object, e.g. enforcing `{ "pattern": "^[a-z]+$" }` on all keys
- prefixItems- (2020-12) Positional tuple validation for arrays: `[stringSchema, numberSchema]` validates index 0 and 1 differently
- contentMediaType / contentEncoding- Documents that a string value is e.g. `"application/json"` encoded as `"base64"`, advisory unless the validator supports content assertions
- const with oneOf (discriminator pattern)- Combine `"const"` on a type-tag field inside each `oneOf` branch to build a poor-man's tagged union without vendor extensions
- readOnly / writeOnly- Annotations (not enforced by validators) telling API tooling a field is server-generated or input-only, e.g. passwords
Set `additionalProperties: false` on objects you fully control to catch typos in payloads early, but leave it open on schemas meant to be extended by consumers to avoid breaking forward compatibility.