JSON Schema Explained: How to Validate API Responses Like a Pro

JSON Schema lets you define the exact structure your API should return and automatically validate every response against it. Here's how it works and why your team should be using it.

JSON Schema Explained: How to Validate API Responses Like a Pro

Your backend says it returns { "price": 29.99 }. Your frontend displays it as a number. One day, a backend developer changes it to { "price": "29.99" } — a string. Your UI breaks. Nobody notices until a user reports it.

This is an API contract violation, and it happens more than it should. JSON Schema is the tool that catches it automatically.

What Is JSON Schema?

JSON Schema is a vocabulary for describing the structure of JSON data. You write a schema — itself a JSON document — that defines what fields exist, what their types are, which ones are required, and what constraints they must satisfy. You can then validate any JSON object against this schema programmatically.

Think of it as a type system for your API responses.

A Simple Example

Suppose your API returns a user object:

{
  "id": 42,
  "name": "Maria Santos",
  "email": "maria@example.com",
  "role": "admin",
  "created_at": "2025-11-01T09:00:00Z"
}

Here's the JSON Schema that describes it:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "name", "email", "role", "created_at"],
  "properties": {
    "id":         { "type": "integer" },
    "name":       { "type": "string", "minLength": 1 },
    "email":      { "type": "string", "format": "email" },
    "role":       { "type": "string", "enum": ["admin", "user", "guest"] },
    "created_at": { "type": "string", "format": "date-time" }
  },
  "additionalProperties": false
}

This schema enforces:

  • id must be an integer (not a string)
  • email must be a valid email format
  • role must be one of three specific values
  • All five fields are required
  • No extra fields are allowed (additionalProperties: false)

Core Schema Keywords

KeywordWhat It Does
typeSpecifies data type: string, number, integer, boolean, array, object, null
requiredArray of property names that must be present
propertiesDefines the schema for each property of an object
enumValue must be one of a specific list
minimum / maximumNumeric range constraints
minLength / maxLengthString length constraints
patternString must match a regex pattern
itemsSchema for items in an array
formatSemantic format hints: email, date-time, uri, uuid

Validating Arrays

For a paginated list response:

{
  "type": "object",
  "required": ["data", "total", "page", "per_page"],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "name"],
        "properties": {
          "id":   { "type": "integer" },
          "name": { "type": "string" }
        }
      }
    },
    "total":    { "type": "integer", "minimum": 0 },
    "page":     { "type": "integer", "minimum": 1 },
    "per_page": { "type": "integer", "minimum": 1, "maximum": 100 }
  }
}

Using JSON Schema in JavaScript

The most popular validator for JavaScript is Ajv:

npm install ajv
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const schema = {
  type: 'object',
  required: ['id', 'name', 'email'],
  properties: {
    id:    { type: 'integer' },
    name:  { type: 'string' },
    email: { type: 'string', format: 'email' }
  }
};

const validate = ajv.compile(schema);
const data = await fetch('/api/users/1').then(r => r.json());

if (!validate(data)) {
  console.error('API response invalid:', validate.errors);
}

Using JSON Schema in PHP (Laravel)

composer require opis/json-schema
use Opis\JsonSchema\Validator;
use Opis\JsonSchema\Helper;

$validator = new Validator();
$schema = Helper::toJSON('{
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id":   {"type": "integer"},
    "name": {"type": "string"}
  }
}');

$result = $validator->validate($data, $schema);
if (!$result->isValid()) {
    // handle validation failure
}

Where to Apply Schema Validation

  • In API tests: Assert that every response matches the schema, not just the status code
  • In integration tests: Catch contract drift between services
  • At runtime (optional): Validate responses from third-party APIs before you process them
  • In documentation: JSON Schema is the basis of OpenAPI — if you write schemas, you're already halfway to full API documentation

JSON Schema and Mock APIs

When you're building mock API responses, writing the JSON Schema first is a powerful technique. Define the contract, mock it with the schema-compliant response, then share the schema with both the frontend and backend teams. Everyone builds to the same spec. When the real implementation is ready, run your schema tests against it to verify nothing drifted.

Conclusion

JSON Schema turns informal API contracts into enforceable specifications. It takes 10 minutes to write a schema for your most important endpoints, and it will save you hours of debugging when a response changes unexpectedly. Start with your most critical endpoints — authentication, payments, user data — and expand from there.