Back to blog
|11 min read|Docsio

What Is JSON Schema? Examples and Guide

json-schemaapi-documentationdatadeveloper-tools
What Is JSON Schema? Examples and Guide

JSON Schema is a standard for describing and validating the structure of JSON data. You write a schema, a small JSON document that declares what fields a payload should contain, their types, and which ones are required. A validator then checks any JSON against that schema and reports exactly what is wrong. It works like a contract for your data.

That contract solves two problems at once: it catches bad data before it breaks your code, and it doubles as living documentation. If you already work with API specs, JSON Schema sits underneath them, the same way it powers the request and response shapes in an OpenAPI specification example. This guide explains what JSON Schema is, shows worked examples, and covers the keywords and types you will use every day.

What is JSON Schema, exactly?

JSON Schema is itself written in JSON. A schema is a set of rules, expressed as keywords, that describe a valid JSON value. The most common use is validation: confirming that an incoming object has the right fields with the right types. The second use is documentation, since a schema reads as a precise description of a data structure.

A plain JSON file tells you what one example looks like. A JSON Schema tells you what every valid example must look like. That difference is why teams adopt it for API request bodies, configuration files, message queues, and form input.

Why JSON Schema matters

Without validation, bad data slips through and surfaces as a confusing error three functions later. With a schema, you reject the bad payload at the door with a clear message. This matters most at system boundaries: API endpoints, webhooks, and config loading.

The documentation benefit is just as practical. A schema is machine-readable, so tools can render it as a reference table, generate sample payloads, or scaffold client code. Good REST API documentation leans on schemas so that the field list a reader sees matches what the server actually enforces.

A basic JSON Schema example

Here is a small schema for a user object. It says a user is an object with a name string, an age integer, and an email string, and that name and email are required.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "User",
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer" },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["name", "email"]
}

This JSON validates against the schema above:

{
  "name": "Ada Lovelace",
  "age": 36,
  "email": "ada@example.com"
}

This JSON fails, because email is missing and age is a string, not an integer:

{
  "name": "Grace Hopper",
  "age": "thirty"
}

JSON Schema data types

Every value in a schema is described by a type keyword. JSON Schema defines seven core types, the same primitives JSON itself supports plus the two container types.

TypeDescribesExample value
stringText"hello"
numberAny numeric value, including decimals3.14
integerWhole numbers only42
objectKey/value collection{ "id": 1 }
arrayOrdered list[1, 2, 3]
booleanTrue or falsetrue
nullThe null valuenull

You can allow more than one type by passing an array, for example "type": ["string", "null"] for a field that may be text or empty.

Common JSON Schema keywords

Keywords are the building blocks of a schema. The table below covers the ones you will reach for in almost every schema.

KeywordWhat it does
$schemaDeclares which JSON Schema version (draft) the document uses
typeSets the allowed data type for a value
propertiesDefines the named fields of an object and their schemas
requiredLists which properties must be present
itemsDefines the schema each element of an array must match
enumRestricts a value to a fixed set of options
formatAdds a semantic hint like email, date-time, or uri
$refReuses another schema by reference instead of repeating it
minimum / maximumSets numeric bounds
minLength / maxLengthSets string length bounds
additionalPropertiesControls whether unlisted fields are allowed

A few of these deserve a closer look.

type, properties, and required

These three keywords do most of the work. type says what kind of value you expect, properties describes each field of an object, and required marks the fields that cannot be omitted. A field listed in properties is optional unless you also name it in required.

enum and format

Use enum when a value must be one of a known list, such as "status": { "enum": ["active", "paused", "closed"] }. Use format to signal intent for strings: email, date, date-time, uri, and uuid are widely supported. Note that format is a hint, and not every validator enforces it by default.

items

items applies a schema to every element in an array. To require an array of strings you write "type": "array", "items": { "type": "string" }. Add minItems or uniqueItems to constrain length or forbid duplicates.

$schema and $ref

$schema points to the draft you are writing against, which tells validators how to interpret the rest of the document. $ref lets you define a shape once and reuse it. If you have an address object used by both a customer and a supplier, you define it once and reference it with $ref in both places. This keeps large schemas readable and consistent, the same discipline a data dictionary brings to a database.

A fuller worked example

The schema below describes a blog post. It uses nested objects, an array of strings with constraints, an enum, a format, numeric bounds, and $ref for a reusable author object.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "BlogPost",
  "type": "object",
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "title": { "type": "string", "minLength": 1, "maxLength": 120 },
    "status": { "enum": ["draft", "published", "archived"] },
    "publishedAt": { "type": "string", "format": "date-time" },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "uniqueItems": true
    },
    "author": { "$ref": "#/$defs/author" }
  },
  "required": ["id", "title", "status"],
  "additionalProperties": false,
  "$defs": {
    "author": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string", "format": "email" }
      },
      "required": ["name"]
    }
  }
}

Setting additionalProperties to false means any field not listed in properties makes the payload invalid. That strictness is useful for catching typos like titel before they reach production.

JSON Schema for API documentation

JSON Schema is the foundation of modern API specs. In OpenAPI, every request body and response is described with a JSON Schema object. So when you document an endpoint, you are really writing schemas. That overlap is why the question of Swagger vs OpenAPI often comes up alongside JSON Schema: Swagger is the older tooling, OpenAPI is the current spec, and both rely on schemas to describe data shapes.

Because a schema is structured data, you can render it into a clean reference page automatically. Tools like Docsio turn your API and schema docs into a branded, searchable site, so the field tables your readers see stay in sync with the rules your server enforces. If you want more patterns to model, our roundup of API documentation examples shows how schemas appear in published docs.

How do you validate JSON against a schema?

Validation is the step where a tool checks a JSON document against your schema and returns pass or fail with error details. You rarely write a validator yourself. Instead you pick a library for your language and feed it the schema plus the data.

Popular validators include Ajv for JavaScript and TypeScript, jsonschema for Python, python-jsonschema bindings, everit-json-schema and networknt for Java, and go-jsonschema style libraries for Go. A typical flow in Node looks like this:

{
  "step1": "Load your schema file",
  "step2": "Create a validator with the schema",
  "step3": "Run validator(data)",
  "step4": "Read the errors array if validation fails"
}

The validator returns a list of errors, each pointing at the exact path that failed, such as /author/email. That precise location is what makes schema validation faster to debug than ad hoc field checks.

JSON Schema tools

A few categories of tooling cover most needs:

  • Validators: Ajv, jsonschema (Python), and similar libraries enforce schemas at runtime.
  • Generators: tools that infer a draft schema from a sample JSON document, giving you a starting point to refine.
  • Online playgrounds: web validators let you paste a schema and a payload to test the result instantly.
  • Editors: many IDEs offer autocomplete and inline validation when a JSON file references a schema.
  • Doc renderers: spec and docs tools render schemas into human-readable reference pages.

Best practices for writing JSON Schema

A few habits keep schemas maintainable as they grow.

  • Always set $schema so validators know which draft to apply.
  • Add a title and description to each schema and field. These flow straight into generated docs.
  • Use $ref for repeated shapes instead of copying objects. One definition, many references.
  • Be deliberate about additionalProperties. Set it to false when you want to reject unexpected fields, and leave it open when you expect forward-compatible extensions.
  • Keep required honest. Mark only the fields your code truly depends on, so optional data does not get rejected.
  • Validate at the boundary. Check incoming data at API entry points and config load, not deep inside business logic.

Conclusion

JSON Schema gives your JSON data a contract: a precise, machine-readable description that validators enforce and documentation tools render. Start with type, properties, and required, add enum, format, items, and $ref as your data grows, and validate at every boundary. The same schemas that catch bad payloads also become the reference your team and your API consumers read. Write the schema once, and let it both guard and document your data.

Frequently asked questions

What is JSON Schema used for?

JSON Schema is used to validate and document the structure of JSON data. Validators check that a payload has the correct fields, types, and required values, rejecting bad data at system boundaries like API endpoints. It also serves as machine-readable documentation that tools can render into reference pages.

What is the difference between JSON and JSON Schema?

JSON is a data format that holds one specific set of values. JSON Schema is a separate JSON document that describes the rules every valid JSON of that kind must follow. In short, JSON is the data, and JSON Schema is the contract that defines and validates the shape of that data.

Is JSON Schema still used?

Yes. JSON Schema is widely used and actively maintained, with the 2020-12 draft as the current stable version. It underpins API specifications like OpenAPI, configuration validation, and form handling across most programming languages, and major tools ship validators and editor support for it.

How do you validate JSON against a schema?

You use a validation library for your language, such as Ajv for JavaScript or jsonschema for Python. You load the schema, pass it the JSON data, and the validator returns whether the data passes plus a list of errors. Each error points to the exact field path that failed.

What are the core JSON Schema data types?

JSON Schema defines seven types: string, number, integer, object, array, boolean, and null. You assign one with the type keyword, or allow several by passing an array of types. These map directly to the value kinds that JSON itself supports.

Ready to ship your docs?

Generate a complete documentation site from your URL in under 5 minutes.

Get Started Free