How to Generate a JSON Schema from a Sample Document
Writing a JSON Schema by hand is slow and error-prone. This guide shows how inferring one from a real example gets you a working draft in seconds, plus how to refine it correctly.
JSON Schema is the closest thing JSON has to a type system - it describes what shape a document should have, which fields are required, and what type each value must be. The trouble is that hand-writing one from scratch is tedious: you have to enumerate every property, get the type keywords right, and keep nested objects and arrays in sync with the real data. Most of the time you already have a perfectly good example sitting in a log file or an API response - you just need it turned into a schema.
That is exactly what the JSON Schema Generator does. Paste a representative sample and it infers types, required keys, and nested structure automatically, giving you a draft schema you can refine rather than write from a blank page. This guide walks through what JSON Schema is for, how inference works, where it falls short, and how to turn a generated draft into something you would actually trust in production.
What a JSON Schema actually describes
A JSON Schema is itself a JSON document that describes the structure of other JSON documents. It states the expected type of each field (string, integer, boolean, object, array, and so on), which properties must be present, and - if you add more constraints - things like string formats, minimum values, or enumerated choices. Validators like AJV read a schema and a candidate document, then tell you whether the document conforms.
Schemas are useful in a lot of places beyond validation: they document an API's contract, drive code generation for typed clients, and give editors enough information to offer autocomplete on config files. The problem most teams run into is that schemas tend to rot - or never get written at all - because maintaining one by hand competes with shipping features.
Why generating a schema beats writing one by hand
If you already have a real payload - a saved API response, a config file, a database export - it already encodes almost everything a schema needs to say: which keys exist, what type each value is, and how arrays and nested objects are shaped. Re-typing that information by hand is slow and invites mismatches between the schema and the data it is supposed to describe.
- Speed - a schema for a moderately nested object takes seconds to generate instead of minutes to write.
- Accuracy to the source - the inferred types come directly from real values, not from someone's memory of the API contract.
- A concrete starting point - it is far easier to edit a draft schema than to stare at a blank JSON Schema document and remember the keyword names.
- Faster onboarding - new documents (a webhook payload, a third-party API response) can be understood structurally in one step.
How the generator infers a schema
The JSON Schema Generator walks your sample document and, for every value it finds, records a matching JSON Schema type - string for text, integer or number for numeric values, boolean for true/false, object for nested records, and array for lists. Every key it observes on an object is added to that object's required list, since a single sample gives no way to know which fields are truly optional.
Arrays are handled by inferring a schema for their items. If an array holds strings, its items schema is { "type": "string" }. If it holds objects - the common case for lists of records - the generator derives an item schema describing those objects, nesting depth-first as far as your sample goes. The result targets a modern JSON Schema draft, so the output works cleanly with mainstream validators.
Sample document to inferred schema
A small user record with a nested tags array, and the schema generated from it.
Input
{
"id": 1001,
"email": "ada@example.com",
"active": true,
"roles": ["admin", "editor"],
"address": {
"city": "London",
"zip": "EC1A 1BB"
}
}Output
{
"type": "object",
"properties": {
"id": { "type": "integer" },
"email": { "type": "string" },
"active": { "type": "boolean" },
"roles": {
"type": "array",
"items": { "type": "string" }
},
"address": {
"type": "object",
"properties": {
"city": { "type": "string" },
"zip": { "type": "string" }
},
"required": ["city", "zip"]
}
},
"required": ["id", "email", "active", "roles", "address"]
}Step-by-step: generate a schema from your own data
- Collect a representative sample - ideally one that includes every field you care about, including any nested objects and arrays.
- Paste it into the JSON Schema Generator.
- Let it infer the type, required-key list, and nested structure for the whole document.
- Review the draft: relax fields that are actually optional, and tighten types where the sample was ambiguous (an integer-looking ID that is sometimes a string, for example).
- Copy the schema and pair it with the JSON Schema Validator to confirm it correctly accepts good documents and rejects bad ones.
Your sample data never leaves your browser
Because inference is pure computation - walking a document and recording types - it runs entirely client-side. The JSON Schema Generator never uploads, logs, or stores what you paste, so it is safe to generate schemas from real API responses, internal records, or anything else you would not want leaving your machine.
Where a generated schema helps most
- Bootstrapping a validation schema from an API response you already have, instead of reading vendor docs line by line.
- Documenting the expected shape of a config file so teammates know what a valid one looks like.
- Producing a contract for a payload before you write integration tests against it.
- Feeding a starting schema into code-generation tooling that turns schemas into typed models.
- Standardizing a data structure across a team by generating from one known-good example and agreeing on it.
What inference cannot know from one sample
Every observed field looks required
A single example cannot tell the generator which fields are sometimes missing. Every key present in your sample gets added to required by default. If a field is genuinely optional - say, a middleName that is absent on some records - you need to remove it from required yourself after generating the draft.
Ambiguous or mixed types
If your sample shows a price as 19.99, the schema will say number. If real data sometimes sends that same field as a string like "19.99", the inferred schema will not know to allow both - it only reflects what it saw. Widen the type manually (for example with a type array) when you know the field is inconsistent in practice.
Empty arrays and null values
An empty array in the sample gives the generator nothing to infer an items schema from, and a null value cannot reveal its real type. Use a sample where every field has at least one representative, non-null value so the generated schema is actually useful.
Best practices for turning a draft into a real schema
- Pick a sample that includes every field you care about, populated with realistic (non-empty, non-null) values.
- Immediately review the
requiredlist and remove anything that is genuinely optional in your data. - Add format constraints (email, date-time, uuid) by hand where the generator only had a generic
stringto work with. - Validate a handful of real documents - including edge cases - against the schema using the JSON Schema Validator before relying on it.
- Re-generate or update the schema whenever the underlying data shape changes, rather than letting it drift out of sync.
Generate from more than one sample
If you have several example documents (different users, different states of an object), run each through the JSON Schema Generator and merge the results by hand. This surfaces fields that are only present sometimes, which a single sample would hide.
Related tools
Validate JSON against a JSON Schema using AJV.
Validate JSON syntax and pinpoint the exact line and column of any error.
Pretty-print JSON with configurable indentation and instant validation.
Turn JSON into clean, readable YAML for configs, pipelines and manifests.
Related guides
A JSON document can be well-formed and still be wrong. This guide explains JSON Schema validation, how AJV catches contract violations, and how to check your data with precise, path-level errors.
A single misplaced comma can break an entire API request. This guide explains how JSON validation works, the mistakes it catches, and how to find the exact error location in seconds.
Minified JSON is unreadable and hard to debug. This guide covers how JSON formatting works, when to use it, common mistakes, and how to pretty-print JSON without uploading it anywhere.
Kubernetes, GitHub Actions and Ansible all expect YAML, but your data often starts life as JSON. Here's how the conversion works, where it trips people up, and how to do it privately in seconds.