JSON Schema Examples - Real-World Schema Patterns

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 →

What is JSON Schema?

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:

Basic Schema Example

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 }
  }
}

Required Properties

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.

Data Type Validation

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.

String Patterns: Email, URL, and Regex

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.

Array Schemas

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).

Nested Object Schemas

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 and Const

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.

Frequently Asked Questions

What is JSON Schema?

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.

What is the difference between type and properties in JSON Schema?

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.

How do I make a field required in JSON Schema?

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.

Which JSON Schema version should I use?

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.

Validate JSON against a schema now

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