Home JSON to JSON Schema

JSON to JSON Schema generator

Paste a JSON array and get a draft 2020-12 schema describing it — required keys, nested objects and recognised string formats, all worked out from the records you paste.

Why it reads every record, not the first one

The usual failure of a JSON-to-type tool is that it looks at one object. The first record's null becomes the type null; a key that happens to be absent from it never appears at all; a field that is 7 in the first row and 7.5 in the fortieth is typed as an integer. Each of those compiles, passes review and breaks on the second page of results.

This reads every record you paste and merges what it finds:

  • A key missing from any record is optional — the marker is on the key, not the value.
  • A key that is sometimes null is nullable — a different statement from optional, and both can be true.
  • Mixed numbers collapse to one number type. A field holding 7 and 9.5 is a number, not "an integer or a number".
  • Recognised string shapes keep their meaning where the target can express it — UUIDs, ISO timestamps, dates, emails and URLs.
  • An empty array says nothing about its elements, so it stays unknown rather than being guessed from a sibling record.

So paste more than one record. Paste the awkward ones — the row with the null, the row missing the optional field, the one from the second page. The output is only as good as the range of the sample, and that is a property of the input, not of the tool.

Required, optional and nullable

JSON Schema keeps these three apart, and the generated schema uses each for what it means:

  • Required — a key present in every record you pasted is listed in required.
  • Optional — a key absent from any record is simply left out of required. There is no "optional" keyword; that absence is the mechanism.
  • Nullable — a key whose value is sometimes null gets a type array, ["string", "null"]. This is the draft 2020-12 spelling; OpenAPI 3.0's nullable: true is a different, older dialect.

Formats it recognises

Where every value in a field matches, the schema records a format: uuid, date-time, date, email and uri. Bear in mind that format is annotation-only by default — most validators do not enforce it unless you turn format assertion on. It is a statement of intent that tooling can read, not a constraint you get for free.

What is not in the output

No $id, no $defs and no additionalProperties: false. Each is a decision about how the schema will be used rather than something a sample can tell you: whether the document has a canonical URL, whether repeated shapes should be factored out and referenced, and whether unknown keys are an error or forward compatibility. Add them deliberately.

Also absent: minimum, maxLength, pattern and enum. All four are constraints a sample can only guess at, and a guessed constraint is a schema that rejects valid data the first time real input arrives.

Common questions

Which draft does it generate?

Draft 2020-12, declared in the $schema keyword. Nullable fields use a type array, which is the 2020-12 spelling — OpenAPI 3.0 nullable: true is a different, older dialect.

How does it decide what is required?

A key present in every record you paste is required; a key absent from any of them is not. There is no optional keyword in JSON Schema — being left out of required is the mechanism.

Does format actually validate anything?

Not by default. In JSON Schema, format is annotation-only unless the validator has format assertion enabled. It records intent that tooling can read rather than a constraint you get automatically.

Why is there no additionalProperties: false?

Because whether unknown keys are an error or forward compatibility is a decision about your API, not something a sample can reveal. The same goes for $id and $defs.

Why are there no minimum or enum constraints?

A sample cannot tell a real constraint from a coincidence. A guessed minimum or a guessed enum produces a schema that rejects valid data the first time real input arrives.

Last updated