What Is JSON Schema? Complete Guide With Examples
Abhay Khant
Jan 1, 1970 • 4 min read
What Is JSON Schema? Complete Guide With Examples
- JSON Schema is a vocabulary for validating JSON structure and values
- Core keywords: type, properties, required, items, enum, format
- Schemas document APIs and catch bad data before runtime does
- Code generators turn schemas into types across languages
What JSON Schema actually is
A JSON Schema is a JSON document that describes the shape, types, and constraints other JSON documents must satisfy. Where JSON defines how data is written, [JSON Schema](https://json-schema.org/) defines what data is acceptable: which fields exist, which are required, what types they carry, and what values count as valid. A schema is itself written in JSON, which means schemas can be validated by schemas, stored alongside code, and shipped wherever the data they govern travels. The [official getting-started guide](https://json-schema.org/learn/getting-started-step-by-step) walks the first schema in about ten minutes.
The practical effect is a contract. Producers know exactly what they may emit, consumers know exactly what they may expect, and a validator enforces both directions without trust or guesswork.
A first schema with annotations
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0 },
"role": { "enum": ["admin", "editor", "viewer"] }
},
"required": ["email"]
}
This schema accepts objects with an email-shaped string (mandatory), an optional non-negative integer age, and an optional role limited to three values. Anything else fails validation with specifics about which constraint broke. The $schema line declares which dialect the document follows, currently [draft 2020-12](https://json-schema.org/specification-links).
The core keywords worth knowing
| Keyword | Purpose | Example |
|---|---|---|
type | Constrains the JSON type | "string", "integer", "array" |
properties | Schemas for object fields | {"name": {"type": "string"}} |
required | Mandatory field names | ["email"] |
items | Schema applied to array elements | {"type": "string"} |
enum | Whitelist of exact values | ["small", "large"] |
format | Semantic string shapes | "email", "uri", "date-time" |
$ref | Reference reusable definitions | "#/definitions/address" |
These seven keywords cover the large majority of real-world validation needs. Compositional keywords (allOf, anyOf, oneOf) layer on top when rules combine, and definitions keeps repeated structures like addresses in one place via $ref.
Why teams bother with schemas
- API contracts: request and response bodies validated on both sides of the wire ([OpenAPI](https://spec.openapis.org/oas/latest.html) builds exactly this pattern into API specifications), turning integration bugs into clear rejection messages
- Configuration safety: config files checked against schema at startup, catching typos before production does; our YAML versus JSON guide notes YAML configs convert to JSON for exactly this pass
- Documentation: a schema is executable documentation that cannot drift from reality the way prose docs do
- Code generation: tools generate typed classes from schemas across dozens of languages, keeping types and contract in lockstep
A practical validation workflow
- Draft the schema for your payload using the keywords above
- Validate sample data against it during development; the JSON schema generator bootstraps schemas from existing JSON when starting from examples rather than scratch
- Wire validation into boundaries: API middleware, CI pipelines, or startup checks
- Version the schema as payloads evolve so old consumers keep working while new fields arrive
The formatter step matters more than beginners expect: malformed JSON fails parsing before validation even begins, so run payloads through the JSON formatter and validator first to separate syntax errors from contract violations.
Schemas versus language types
TypeScript developers sometimes ask why schemas matter when static types exist. The two solve different halves of the problem: TypeScript proves your code matches types at compile time, but says nothing about the JSON arriving over the network at runtime. A schema validates the wire format where types cannot reach. Teams doing serious API work use both, generating types from schemas so the compile-time world and the wire contract stay synchronized. Our comparison of JSON Schema versus TypeScript types walks that division of labor in detail.
Common schema mistakes
| Mistake | Consequence | Fix |
|---|---|---|
Forgetting required | Everything optional by default | List mandatory fields explicitly |
Using format expecting enforcement | Formats are annotations in most validators | Add regex or enable format-assertion mode |
| Duplicating nested structures | Drift between copies over time | Extract shared parts into definitions |
| Validating only happy-path samples | Gaps discovered in production | Test deliberately broken payloads too |
Working with JSON Schema from here
A JSON Schema turns implicit expectations into explicit, machine-checkable contracts. Start small: pick one payload you care about, write its schema with the seven core keywords, validate real samples against it, and let the failure messages teach you the vocabulary. Within a week the habit spreads to every boundary where untrusted data enters your system, which is precisely where validation earns its keep.


