Generating JSON Schema from Example Data: A Practical Guide
June 5, 2026 · 4 min read
JSON Schema is a vocabulary for describing the structure and constraints of JSON data. It's used for API documentation, request validation, code generation, and IDE autocompletion. Writing one from scratch can be tedious — but you can generate a first draft automatically from an example JSON document.
This guide covers how JSON Schema works, how auto-generation from examples works, and how to use the generated schema in practice.
What is JSON Schema?
A JSON Schema is itself a JSON document that describes the shape of other JSON data. For example, this JSON:
{ "name": "Alice", "age": 30, "active": true }
Has this schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"active": { "type": "boolean" }
},
"required": ["name", "age", "active"],
"additionalProperties": false
}
The schema says: this must be an object with exactly three properties — a string, an integer, and a boolean — all required.
Why use JSON Schema?
API validation
Validate request bodies before they reach your business logic:
// Using the ajv library
import Ajv from 'ajv';
const ajv = new Ajv();
const validate = ajv.compile(schema);
if (!validate(requestBody)) {
return res.status(400).json({ errors: validate.errors });
}
Code generation
Generate TypeScript types from a JSON Schema using json-schema-to-typescript:
npx json-schema-to-typescript schema.json > types.ts
The JSON to TypeScript tool does this directly in the browser.
Documentation
Tools like OpenAPI/Swagger use JSON Schema internally. If you're documenting a REST API, your schema is already part of the contract.
Editor autocompletion
VS Code reads JSON Schema from $schema URLs. Add a schema reference to your config files for autocomplete:
{
"$schema": "https://json.schemastore.org/package",
"name": "my-project"
}
How auto-generation from examples works
The JSON Schema Generator analyzes your JSON document and infers:
- Types —
string,number,integer,boolean,null,array,object - String formats — detects
email,uri, anddate-timepatterns - Required fields — marks non-null properties as required
- Nested objects — recurses into nested structures
- Arrays — uses the first item to infer the item schema
For example, this input:
{
"user": {
"email": "[email protected]",
"score": 98.5,
"tags": ["admin", "user"],
"createdAt": "2024-01-15T10:30:00Z"
}
}
Produces:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Root",
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"score": { "type": "number" },
"tags": { "type": "array", "items": { "type": "string" } },
"createdAt": { "type": "string", "format": "date-time" }
},
"required": ["email", "score", "tags", "createdAt"],
"additionalProperties": false
}
},
"required": ["user"],
"additionalProperties": false
}
Use this as a starting point, not a finished schema. The generator can't know about optional fields, minimum/maximum values, pattern constraints, or enum values — you'll need to add those manually.
Common manual adjustments
Optional fields
Remove a field from required to make it optional:
"required": ["name", "email"] // age is now optional
Value constraints
Add minimum, maximum, minLength, maxLength, pattern:
{ "type": "integer", "minimum": 0, "maximum": 120 }
{ "type": "string", "minLength": 3, "maxLength": 100 }
{ "type": "string", "pattern": "^[A-Z]{2}[0-9]{10}$" }
Enum values
When a field has a fixed set of allowed values:
{ "type": "string", "enum": ["pending", "active", "cancelled"] }
Union types / nullable
For a field that can be a string or null:
{ "type": ["string", "null"] }
Or with Draft 2020-12 style:
{ "oneOf": [{ "type": "string" }, { "type": "null" }] }
Arrays with mixed item types
The auto-generator infers from the first item. For mixed arrays, use items: {} (allow anything) or oneOf:
{
"type": "array",
"items": {
"oneOf": [
{ "type": "string" },
{ "type": "number" }
]
}
}
JSON Schema drafts
The generator targets Draft 2020-12, the current stable version. Key differences from older drafts:
| Feature | Draft 7 | Draft 2020-12 |
|---|---|---|
$ref in any schema |
Restricted | Allowed alongside siblings |
definitions |
Standard | Use $defs instead |
items for tuples |
items: [...] |
prefixItems: [...] |
unevaluatedItems |
No | Yes |
Most validators (ajv, Zod, Yup) support Draft 7; Draft 2020-12 support is increasingly common.
Practical workflow
- Paste your example JSON into the JSON Schema Generator
- Copy the output schema
- Review and adjust: mark optional fields, add constraints, fix enum values
- Paste the schema into JSON Tree Viewer to inspect its structure visually
- Test validation with a sample valid/invalid document
- Add it to your API documentation or validation layer
For exploring unknown JSON structures before writing a schema, the JSON Tree Viewer is especially useful — it gives you a collapsible view of all keys and value types.
Schema stores
If you're writing a config file for a well-known tool (ESLint, Prettier, TypeScript, GitHub Actions), a pre-written schema likely already exists at SchemaStore.org. These schemas are more complete than anything you could auto-generate and include documentation in descriptions.
Use the JSON Formatter to pretty-print any schema you find or generate before reading it.