DevLab
JSON

JSON Schema Explained: Validate Your JSON Data

Learn how JSON Schema works, how to write validation rules for objects and arrays, and how to use it for API request validation and OpenAPI documentation.

What is JSON Schema?

JSON Schema is a vocabulary for describing the structure of JSON data. It is itself a JSON document that defines what other JSON documents should look like — their types, required fields, allowed values, and nested structures. Think of it as a type system for JSON that works at runtime, without compilation.

Basic Structure

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name":  { "type": "string", "minLength": 1 },
    "age":   { "type": "integer", "minimum": 0, "maximum": 150 },
    "email": { "type": "string", "format": "email" }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

Type Keywords

  • "type": "string" — any string value
  • "type": "number" — integer or float
  • "type": "integer" — whole numbers only
  • "type": "boolean" — true or false
  • "type": "array" — JSON array
  • "type": "object" — JSON object with key-value pairs

Common Constraints

// Strings
"minLength": 1, "maxLength": 100
"pattern": "^[a-z0-9-]+$"

// Numbers
"minimum": 0, "maximum": 100
"multipleOf": 5

// Arrays
"items": { "type": "string" }
"minItems": 1, "maxItems": 10
"uniqueItems": true

// Enums
"enum": ["active", "inactive", "pending"]

Reusable Definitions with $ref

{
  "type": "object",
  "properties": {
    "address": { "$ref": "#/$defs/Address" }
  },
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city":   { "type": "string" }
      },
      "required": ["street", "city"]
    }
  }
}

Practical Uses

  • API request validation: Libraries like Zod, Yup, and Ajv validate request bodies against a schema at runtime
  • Documentation: OpenAPI/Swagger uses JSON Schema to document request and response shapes
  • IDE autocomplete: VS Code uses JSON Schema to provide autocomplete for tsconfig.json, package.json, and other config files
  • Database input sanitization: Validate data before inserting to catch type mismatches early

Frequently Asked Questions

What is the difference between JSON Schema and TypeScript types?

TypeScript types exist only at compile time and are erased when code is transpiled to JavaScript — they cannot validate data at runtime. JSON Schema is a runtime validation specification: you write a schema document and use a validator library (like Ajv or Zod with .json() export) to check incoming data against it. TypeScript catches type errors in your own code; JSON Schema catches invalid data from external sources like API requests, config files, or database records. Many projects use both: TypeScript for internal type safety and JSON Schema for boundary validation.

Which JSON Schema draft version should I use?

Use Draft 2020-12 (the latest stable draft) for new projects. It introduced prefixItems for tuple validation, $dynamicRef for extensible schemas, and cleaner vocabulary support. If you are working with an existing codebase, check which draft your validator supports — Ajv v8 supports Draft 2020-12 and 2019-09, while older versions of Ajv only support Draft-07. Draft-07 is still the most widely deployed version and is perfectly adequate for most use cases. Avoid Draft-04 unless you are maintaining legacy systems that depend on it.

Can JSON Schema validate that a string is a valid email or URL?

JSON Schema has a format keyword with values like 'email', 'uri', 'date-time', and 'ipv4'. However, format validation is optional by default in most validators — Ajv, for example, requires you to explicitly enable format validation with the ajv-formats plugin. Even when enabled, format validation checks structural validity (like whether an email has an @ sign and a domain) but does not verify that the address actually exists or that a URL resolves. For strict validation, combine format with a pattern constraint or validate at the application layer after schema validation passes.

Practice with these tools

More Learning Topics

RegexRegex Basics: A Complete Beginner's GuideRegexRegex Special Characters: Complete ReferenceRegexRegex Groups and Captures ExplainedRegexRegex Quantifiers: Complete GuideCSSCSS Selectors: The Complete GuideCSSCSS Specificity: Why Your Styles Aren't ApplyingJSONJSONPath Syntax: Query JSON Like XPathTimeUnix Timestamps ExplainedEncodingBase64 Encoding ExplainedEncodingJWT Structure and How It WorksEncodingJWT vs Session Tokens: Which Should You Use?EncodingJWT Refresh Tokens ExplainedCryptoHash Functions Explained: MD5, SHA-256, and When to Use EachEncodingURL Encoding Explained: What %20 Actually MeansJSONJSON vs YAML: Which Should You Use?JSONJSON.stringify and JSON.parse: Edge Cases You Should KnowRegexRegex Lookahead and Lookbehind: Match Without ConsumingRegexRegex for Email Validation: The Right ApproachCSSThe CSS Box Model: margin, padding, border, and contentCSSFlexbox vs CSS Grid: When to Use EachCSSCSS Custom Properties (Variables) ExplainedTimeISO 8601 Explained: The Right Way to Format DatesTimeUnix Timestamps vs ISO 8601: Which to Use in Your API?EncodingUTF-8 Explained: How Computers Store TextTextCORS Explained: Why Your API Call is BlockedTextHTTP Status Codes: A Practical Developer GuideRegexNamed Capture Groups in Regex: Clean ExtractionsColorsColor Spaces Explained: RGB, HSL, HEX, and BeyondColorsColor Contrast for Developers: WCAG Rules and How to CheckNumbersNumber Bases Explained: Binary, Octal, Decimal, and HexNumbersBitwise Operations for Web DevelopersHTMLHTML Semantic Elements: A Complete ReferenceTextText Encoding for Developers: ASCII, UTF-8, and UnicodeRegexWhat is Regex? Complete Guide for DevelopersJSONJSON Format Explained: Structure, Syntax, and Common ErrorsEncodingHow JWT Works: Header, Payload, Signature DecodedHTMLHow to Convert Any Website to Markdown (for LLMs, RAG & Docs)TextPreparing Website Content for RAG: Clean Markdown Pipelines