JSON Schema Validation and API Contracts: OpenAPI, Contract Testing, and Validation Libraries
JSON Schema validates structure and constraints β and OpenAPI uses it as the contract format for API documentation, client SDK generation, and contract testing. Here's how JSON Schema works, key validation keywords, how OpenAPI extends it, and how Pact implements consumer-driven contract testing.
By sadiqbd Β· June 10, 2026
JSON Schema is how you turn a flexible JSON format into a contract that automatically validates β and it's the foundation of OpenAPI
JSON's flexibility is a feature and a problem simultaneously. A flexible API that accepts any JSON it receives is easy to implement and impossible to use reliably β callers don't know what to send, and the server doesn't know what to expect. JSON Schema solves this by defining the structure, types, and constraints that valid JSON must satisfy, and enabling automated validation at any point in the request/response lifecycle.
JSON Schema: the basics
A JSON Schema is itself a JSON document that describes the shape of another JSON document.
Simple example β a user object:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://api.example.com/schemas/user.json",
"type": "object",
"title": "User",
"description": "A registered user account",
"required": ["id", "email", "name"],
"additionalProperties": false,
"properties": {
"id": {
"type": "integer",
"description": "Unique user identifier",
"minimum": 1
},
"email": {
"type": "string",
"format": "email",
"maxLength": 254
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"role": {
"type": "string",
"enum": ["admin", "editor", "viewer"],
"default": "viewer"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"preferences": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
}
What this enforces:
id,email, andnameare required β absent = validation failureidmust be an integer β₯ 1emailmust match email formatrolemust be one of three specific values (or absent, with defaultviewer)- No extra properties are allowed (
additionalProperties: false)
Key JSON Schema keywords
Type validation:
"type": "string" // string only
"type": ["string", "null"] // string or null
"type": "integer" // integers only (no floats)
"type": "number" // integers and floats
"type": "array"
"type": "object"
"type": "boolean"
String constraints:
"minLength": 1
"maxLength": 255
"pattern": "^[a-zA-Z0-9_]+$" // regex pattern
"format": "email" // built-in formats (implementation-dependent)
"format": "date-time" // ISO 8601 datetime
"format": "uri"
Number constraints:
"minimum": 0
"maximum": 100
"exclusiveMinimum": 0 // > 0, not β₯ 0
"multipleOf": 5 // must be divisible by 5
Array constraints:
"minItems": 1
"maxItems": 10
"uniqueItems": true // no duplicates
"items": { "type": "string" } // all items must be strings
Composition:
"allOf": [...] // must match all schemas
"anyOf": [...] // must match at least one
"oneOf": [...] // must match exactly one
"not": { ... } // must NOT match this schema
OpenAPI / Swagger: JSON Schema for APIs
OpenAPI (formerly Swagger) is an API description format that uses JSON Schema (with some extensions and restrictions) to describe request and response bodies. An OpenAPI specification is the complete contract for an API.
# OpenAPI 3.1 specification fragment
paths:
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
minimum: 1
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
components:
schemas:
User:
type: object
required: [id, email, name]
properties:
id:
type: integer
email:
type: string
format: email
name:
type: string
What OpenAPI provides:
- Human-readable documentation
- Machine-readable contract (client SDKs can be auto-generated)
- Validation middleware (validate requests and responses against the spec)
- Mock servers (generate test responses from the spec)
- Interactive documentation (Swagger UI, Redoc)
Contract testing between services
In microservices architectures, services communicate via APIs. Contract testing verifies that the actual messages exchanged between services match their agreed specifications β catching breaking changes before they reach production.
Consumer-Driven Contract Testing (CDCT):
The consumer (client) defines what it expects from the provider (server). The provider verifies it satisfies the consumer's expectations. Tools like Pact implement this:
- Consumer defines expected interactions (request + response format)
- Pact generates a "pact file" (contract)
- Provider runs pact verification: does the actual provider behaviour satisfy the consumer's expectations?
- If yes: contract is verified; deploy with confidence
- If no: breaking change detected before reaching production
Benefits vs. integration tests:
- Contracts run without requiring both services to be running simultaneously
- Faster than full integration testing
- Specifically pinpoints which contract is broken when a service changes
Validation libraries by language
JavaScript / TypeScript:
ajv(Another JSON Validator): the most popular, fast, supports JSON Schema draft-07 to 2020-12zod: TypeScript-first schema definition and validation; infers TypeScript types from schemas
Python:
jsonschema: standard JSON Schema validation librarypydantic: data validation library with JSON Schema export
Java:
json-schema-validator(networknt): supports JSON Schema drafts
Go:
gojsonschemasanthosh-tekuri/jsonschema
Practical JSON Schema workflow
- Define schemas alongside your API code (in a
/schemasdirectory) - Validate on input β reject requests that don't match the expected schema with a clear error message
- Validate on output β in development/testing, validate responses to catch bugs in the server code
- Generate documentation β OpenAPI specs auto-generate interactive docs
- Generate client SDKs β tools like OpenAPI Generator produce typed client libraries for TypeScript, Python, Go, Java, and others
How to use the JSON Formatter on sadiqbd.com
- Paste any JSON β including schema documents
- Format and validate β syntax errors are highlighted
- Use during schema development β format the JSON Schema document itself to verify it's valid JSON before testing it against data
- Inspect API responses β format raw API responses to understand the structure before writing schemas for them
Frequently Asked Questions
What's the difference between JSON Schema validation and TypeScript typing? TypeScript types are compile-time β they catch errors during development when you write code. JSON Schema validation is runtime β it catches errors when the running application receives data. Both are valuable: TypeScript prevents mistakes in your own code; JSON Schema prevents the API from accepting malformed input from external callers.
Should I write schemas manually or generate them?
For new APIs, writing schemas manually as part of API design is best practice. For existing APIs without schemas, tools like quicktype can infer schemas from example JSON responses. Review generated schemas carefully β they may be overly permissive.
Is the JSON Formatter free? Yes β completely free, no sign-up required.
JSON Schema transforms JSON from a flexible format into a validated contract. Combined with OpenAPI for API documentation and contract testing for microservices, it's the foundation of reliable, well-documented API design.
Try the JSON Formatter free at sadiqbd.com β validate, format, and inspect any JSON, including JSON Schema documents.