JSON to JSON Schema
Generate a JSON Schema (Draft 2020-12) from a JSON document.
Related Tools
Generate TypeScript interfaces from a JSON Schema document.
Validate JSON against a JSON Schema with JSON-pointer error paths.
Generate TypeScript interfaces or type aliases from JSON.
Generate Go structs with JSON tags from a JSON document.
Generate Python dataclasses from a JSON document.
Generate a Zod validation schema and TypeScript type from a JSON document.
Documentation
What is JSON to JSON Schema?
This tool infers a JSON Schema (Draft 2020-12) from a sample JSON document — the same type-inference pass used by every generator in this category (TypeScript, Zod, Go, Java, and the rest), just emitting a schema document instead of a language-specific type declaration.
How it works
The sample is parsed into the same internal type tree every other generator on this site builds from — strings, numbers (split into integer/number), booleans, arrays, and nested objects, each object given a name derived from its key. Each distinct object shape becomes its own entry under $defs, and the root schema is a single $ref into that root object's definition — the same "declare each nested type once, reference it elsewhere" decomposition the TypeScript and Zod generators use, just expressed in JSON Schema's own referencing syntax instead of interface/z.object declarations. Every key present with a non-null value in the sample is added to that object's required array; additionalProperties: false is set on every object, since a single sample defines a closed shape by default — loosen it by hand if your real data legitimately carries extra fields the sample didn't show.
Features
- Draft 2020-12 output with a
$schemadeclaration - Nested objects split into named
$defsentries, not one deeply nested blob - Integers and floats distinguished (
integervs.number) - Present, non-null keys marked
requiredautomatically - Null values and empty arrays get an honest description instead of a guessed type
Example
Input:
{
"name": "DevFormats",
"rating": 4.9,
"free": true,
"logo": null,
"tags": ["json", "yaml"]
}Output:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "#/$defs/Root",
"$defs": {
"Root": {
"type": "object",
"properties": {
"name": { "type": "string" },
"rating": { "type": "number" },
"free": { "type": "boolean" },
"logo": { "description": "Sample value was null — no type could be inferred." },
"tags": { "type": "array", "items": { "type": "string" } }
},
"required": ["name", "rating", "free", "tags"],
"additionalProperties": false
}
}
}Common errors
A schema generated from one sample is only as complete as that sample — a field that's sometimes a string and sometimes a number will be typed as whichever it was in your sample, and validating a document where that field holds the other type will fail even though your real API considers both valid. There's no way to fix this from a single input; paste the most representative sample you have, and hand-edit the type keyword to an array (e.g. ["string", "number"]) for any field you know varies.
Best practices
Run the output through JSON Schema Validator against a handful of real documents — including edge cases the original sample didn't cover — before relying on it in a pipeline. additionalProperties: false is the most common thing worth loosening: if your real payloads carry fields beyond what one sample happened to show, either add them explicitly or relax that constraint per object.
Frequently Asked Questions
What happens to a field that was null in my sample?▾
It gets no "type" keyword at all — just a description noting the sample value was null, so the schema validates any type for that field rather than fabricating a guess like "string" that might be wrong in production data.
What happens to an empty array?▾
Same honesty policy: an empty array has no element to infer a type from, so its items schema carries only a description explaining why, not a made-up type.
Are nested objects inlined or split into $defs?▾
Split into $defs, one entry per distinct object shape found in your sample, with the root schema being a single $ref into $defs. That mirrors how every other generator on this site (TypeScript, Zod, Java) declares nested types as separate named declarations rather than one deeply nested blob.
Does the output mark required vs optional fields?▾
Yes — every key present with a non-null value in your sample is added to that object's "required" array. A key that was null is treated as not required, since a single null sample can't tell you whether the field is always present but nullable, or sometimes absent entirely.