A JSON validator tells you whether a document is syntactically valid JSON. JSON Schema goes further: it describes what a valid document should look like, including which fields are required, what type each value has, which values are allowed, and how nested objects are shaped. Schemas are used to validate API requests, document APIs (OpenAPI is built on JSON Schema), check configuration files, and power autocomplete in editors.
This schema describes a user object:
json{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "additionalProperties": false, "required": [ "id", "email", "role" ], "properties": { "id": { "type": "integer", "minimum": 1 }, "email": { "type": "string", "format": "email" }, "role": { "type": "string", "enum": [ "admin", "editor", "viewer" ] }, "active": { "type": "boolean" } } }
And a document that passes it:
json{ "id": 42, "email": "test@example.com", "role": "admin", "active": true }
type: one of object, array, string, number, integer, boolean or null. Use an array such as ["string", "null"] to allow several types.properties: a schema for each named key of an object.required: keys that must be present. Properties aren't required unless they're listed here.additionalProperties: set to false to reject keys you didn't define, which catches typos like emial.enum and const: restrict a value to a fixed set or a single value.minimum, maximum, minLength, maxLength, pattern: numeric ranges, string lengths and regular expressions.items, minItems, uniqueItems: rules for arrays and their elements.format: semantic hints such as email, date-time, uri and uuid. Many validators only check formats when you enable it.json{ "type": "object", "required": ["items"], "properties": { "items": { "type": "array", "minItems": 1, "items": { "type": "object", "required": ["sku", "quantity"], "properties": { "sku": { "type": "string" }, "quantity": { "type": "integer", "minimum": 1 } } } } } }
Put shared shapes in $defs and reference them with $ref:
json{ "$defs": { "address": { "type": "object", "required": ["city"], "properties": { "city": { "type": "string" }, "zip": { "type": "string" } } } }, "type": "object", "properties": { "billing": { "$ref": "#/$defs/address" }, "shipping": { "$ref": "#/$defs/address" } } }
In JavaScript, Ajv is the most widely used validator:
javascriptimport Ajv from 'ajv'; const ajv = new Ajv({ allErrors: true }); const validate = ajv.compile(schema); if (!validate(data)) console.log(validate.errors);
In Python, use the jsonschema package: jsonschema.validate(instance=data, schema=schema).
allErrors: true in Ajv) so users see every problem at once. That pairs well with the field-level details in API error payloads.$schema, because keywords differ slightly between drafts (draft-07 vs 2020-12).Remember that a schema only checks structure. Business rules that span several fields or need a database lookup, such as "the email isn't already registered", still belong in application code.