JSON to JSON Schema

Paste a document and get a schema describing it — a starting point to edit, not a finished specification. It runs in your browser and nothing is uploaded.

Files never leave your device
0

On when the sample IS the contract. Off when it is one example among many, where a missing key proves nothing.

Writing a JSON Schema by hand from a large API response is tedious and easy to get subtly wrong. This page does the mechanical part: it reads a sample document and writes the structure and types it observes, leaving you to add the judgement a sample cannot supply.

What a sample can and cannot prove

This distinction is the whole story of using a generated schema well:

A sample provesA sample cannot prove
These keys existWhether other keys are allowed
This value is a stringWhether it must match a pattern or format
This value is 42Whether the range is 1–100 or unbounded
This key is presentWhether it is required or merely present here
This array holds objectsWhether it may be empty, or has a length limit

The generator is deliberate about staying on the left-hand column. Everything on the right is left for you to add, because inventing a constraint is how a generated schema starts rejecting valid documents three months later.

Integer versus number

The type is decided by how a number is written, not by what it equals:

  • 42 becomes integer
  • 42.0 becomes number
  • 4.2e1 becomes number
  • 123456789012345678901234567890 becomes integer

That last one is the case that separates this from most generators. Because numbers keep their source text rather than being parsed into a double first, a 30-digit identifier is still recognised as an integer instead of being demoted the moment it stops fitting.

Arrays with mixed items

Every element is described, then the descriptions are merged into one items schema:

  • Objects union their properties. A key that appears in some elements and not others still gets a property entry, so nothing is lost.
  • Required keeps only the keys present in every element. One absence is proof the key is optional, and that is the strongest inference a sample supports.
  • Plain values of differing types widen into a union, so [1, "two"] produces {"type": ["integer", "string"]} rather than a guess from the first element.
  • An empty array gets no items at all.
Tip: Feed the generator the widest sample you have — several records rather than one, including the ones with optional keys missing. The array merge above is what turns that breadth into an accurate required list.

Required, and when to turn it off

The switch decides whether every key present in the sample is listed as required:

  • On when the sample is the contract — a config file, a fixture, a request body you control.
  • Off when the sample is one response among many. A key you happened not to receive this time would otherwise become mandatory forever.

Inside arrays the tool applies the stricter rule automatically, regardless of the switch: a key missing from any single element is never required for that item.

Then validate against it

A generated schema earns its keep once you have edited it — added the formats, tightened the ranges, decided what is genuinely optional. The validator on the sibling page checks a document against it and reports every rule that fails, also entirely in your browser.

Frequently asked questions

Is my sample uploaded anywhere?
No. The document is read inside your browser tab by a Rust engine compiled to WebAssembly, and no request carries it off the device. That matters here more than it might seem: the natural way to use a schema generator is to paste a real API response, which is exactly the thing you should not be pasting into someone else's server.
Is the generated schema ready to use as-is?
Treat it as a first draft. A sample can only describe what it happens to contain, so the output has no formats, no ranges, no patterns, and no knowledge of keys the sample never showed. It gets the structure and the types right, which is the tedious part, and leaves the judgement to you.
Why is a key marked required when it is actually optional?
Because it was present in the sample, and presence is the only evidence a single document offers. Turn off the require-all switch when your sample is one example among many rather than the contract itself. For arrays the tool is already careful: a key missing from any one element is left out of that item's required list.
How does it decide between integer and number?
By the source text, not the value. A number written without a decimal point or exponent becomes integer; anything else becomes number. That also means a 30-digit integer is still called an integer, where a generator that parses to a double first would demote it once the value stopped fitting.
What happens with an array whose items are not all alike?
The item schemas are merged. Objects union their properties, and the required list keeps only keys present in every element. Plain values of differing types widen into a type union, so an array of numbers and strings produces a single items schema accepting both rather than a guess based on the first element.
Why does an empty array produce no items schema?
Because an empty array is evidence of nothing. Writing an items rule for it would invent a constraint the sample never demonstrated, and inventing constraints is exactly how a generated schema starts rejecting valid documents later.
Which draft does it write?
2020-12 by default, with Draft 07 available for systems that have not moved. The choice only changes the declared schema keyword and the vocabulary used; the structure inferred from your sample is the same either way.