Practical JSON Schema examples covering user objects, API responses, nested arrays, string patterns, enums, and validation rules. Use these patterns as a starting point for your own schemas.
Try JSON Schema Validator →JSON Schema is a vocabulary for annotating and validating JSON documents. It is specified by an IETF standard (currently Draft 2020-12) and lets you define the structure, data types, required fields, value constraints, and string patterns for any JSON document. Think of it as a contract: a schema describes what valid data must look like, and a validator checks whether actual data conforms to that contract.
JSON Schema is used across many scenarios:
The simplest possible JSON Schema validates that a value is a string:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "string"
}
Valid: "hello world" - Invalid: 42
A basic object schema with type and properties:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"email": { "type": "string" },
"age": { "type": "integer", "minimum": 0, "maximum": 120 }
}
}
Use the required array to mark fields that must be present. Without it, all properties are optional:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"username": { "type": "string", "minLength": 3, "maxLength": 30 },
"email": { "type": "string", "format": "email" },
"password": { "type": "string", "minLength": 8 },
"role": { "type": "string", "default": "user" }
},
"required": ["username", "email", "password"],
"additionalProperties": false
}
additionalProperties: false rejects any keys not listed in properties. This is useful for strict API contracts where unexpected fields should cause a validation error.
JSON Schema supports all JSON primitive types. Here is a reference schema that exercises every type keyword:
{
"type": "object",
"properties": {
"count": { "type": "integer", "minimum": 1 },
"price": { "type": "number", "exclusiveMinimum": 0 },
"label": { "type": "string" },
"active": { "type": "boolean" },
"tags": { "type": "array" },
"metadata": { "type": "object" },
"deletedAt": { "type": ["string", "null"] }
}
}
Note that integer and number are distinct: integer rejects decimals like 3.14, while number accepts both. The type array ["string", "null"] allows a value to be either a string or null — useful for nullable fields in APIs.
Use format for semantic validation and pattern for custom regex constraints:
{
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"website": {
"type": "string",
"format": "uri"
},
"phoneUS": {
"type": "string",
"pattern": "^\\+1[2-9]\\d{9}$"
},
"hexColor": {
"type": "string",
"pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
},
"postalCodeUK": {
"type": "string",
"pattern": "^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
The format keyword is an annotation by default. Whether it is enforced depends on your validator — Ajv enforces it when you pass { formats: require("ajv-formats") }. Common format values include: email, uri, date, date-time, time, uuid, ipv4, ipv6, hostname.
Use items to define the schema for array elements, and minItems / maxItems to constrain length:
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
},
"scores": {
"type": "array",
"items": { "type": "number", "minimum": 0, "maximum": 100 }
},
"coordinates": {
"type": "array",
"items": { "type": "number" },
"minItems": 2,
"maxItems": 2
}
}
}
uniqueItems: true ensures no duplicate values. The coordinates example shows a tuple-style array with exactly 2 numbers (latitude/longitude).
A real-world user profile schema with nested address and preferences objects:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"username": { "type": "string", "minLength": 3 },
"email": { "type": "string", "format": "email" },
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"country": { "type": "string", "minLength": 2, "maxLength": 2 },
"zip": { "type": "string" }
},
"required": ["city", "country"]
},
"preferences": {
"type": "object",
"properties": {
"theme": { "type": "string", "enum": ["light", "dark", "system"] },
"notifications": { "type": "boolean" },
"language": { "type": "string", "default": "en" }
}
},
"roles": {
"type": "array",
"items": { "type": "string", "enum": ["admin", "editor", "viewer"] },
"uniqueItems": true
}
},
"required": ["id", "username", "email"]
}
enum restricts a value to a specific set of allowed values. const pins a value to a single exact value:
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["pending", "active", "suspended", "deleted"]
},
"currency": {
"type": "string",
"enum": ["USD", "EUR", "GBP", "JPY", "INR"]
},
"schemaVersion": {
"const": "2.0"
},
"priority": {
"type": "integer",
"enum": [1, 2, 3]
}
}
}
enum can contain mixed types — strings, numbers, booleans, even null. const is equivalent to an enum with a single value and is used to pin a schema version or a fixed field value in a discriminated union.
JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. It is defined by a series of IETF drafts (currently Draft 2020-12) and lets you describe the structure, data types, required fields, string patterns, value ranges, and more for any JSON document.
The type keyword specifies the data type of a value (string, number, integer, boolean, array, object, null). The properties keyword defines the expected keys of a JSON object and the schema each value must conform to. You typically use both together: type sets the object type, and properties defines its structure.
Use the required keyword at the object level, passing an array of property names that must be present. For example: { "type": "object", "required": ["email"] }. Note that required is separate from properties and applies to the parent object, not to individual property definitions.
For new projects, use Draft 2020-12 (the latest standard) or Draft 2019-09. Legacy projects often use Draft-07, which is still widely supported by validators like Ajv. The core keywords (type, properties, required, enum, items) are consistent across all drafts.
Paste your JSON and schema, get instant validation results. Free, no signup.
Try JSON Schema Validator →Also useful: JWT Decoder | JSON Validator | JSON Formatter | JSONPath Tutorial | JSON to Zod