Skip to content

JSON Schema generator from sample JSON

Turn a sample of your JSON into a draft 2020-12 JSON Schema, inferred from every record, not just the first.

The schema is generated on this device. Your JSON is never uploaded. How your data stays local.

Local
source
result

        
      
Loading the workspace...

JSON Mill's schema generator reads your JSON and writes a draft 2020-12 JSON Schema that describes it: the type of every value, the properties of every object, the items of every array, which keys are required, and formats such as date and email where every value fits.

It looks at every record, not only the first, so a key that is missing from some orders is not marked required, and a field that is sometimes a number and sometimes null gets both types. The schema is generated in your browser and nothing is uploaded.

How to generate a JSON Schema

  1. Paste or open sample JSON. Paste a document into the source panel or drop a file on the workspace. A few hundred representative records give a better schema than one. JSON Lines works too: every line counts as a record.
  2. Choose the options. Keep Enums for repeated text values and Formats on, or turn them off for a looser schema. Under Required keys, choose Keys in every record or None.
  3. Press Generate schema. The schema appears in a read-only box under the options, indented with 2 spaces.
  4. Copy, download or keep working. Press Copy or Download to take the schema with you. Use as document opens it in the editor so you can tighten it, and Validate with it checks your document against it straight away.

Example: a schema from three product records

Three products from a store export. Only two have a discount, and price is sometimes written with decimals and sometimes without.

products.json
[
  {"sku": "TL-100", "name": "Trail Lantern", "price": 34.5, "stock": 12, "added": "2026-09-14", "url": "https://example.com/p/tl-100", "tags": ["camping", "lighting"]},
  {"sku": "CC-200", "name": "Cedar Camp Chair", "price": 89, "stock": 0, "added": "2026-10-02", "url": "https://example.com/p/cc-200", "tags": [], "discount": null},
  {"sku": "WB-300", "name": "Wool Blanket", "price": 61.25, "stock": 7, "added": "2026-10-20", "url": "https://example.com/p/wb-300", "tags": ["home"], "discount": 0.15}
]
Schema JSON Mill generates
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "sku": {
        "type": "string"
      },
      "name": {
        "type": "string"
      },
      "price": {
        "type": "number"
      },
      "stock": {
        "type": "integer"
      },
      "added": {
        "type": "string",
        "format": "date"
      },
      "url": {
        "type": "string",
        "format": "uri"
      },
      "tags": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "discount": {
        "type": [
          "number",
          "null"
        ]
      }
    },
    "required": [
      "sku",
      "name",
      "price",
      "stock",
      "added",
      "url",
      "tags"
    ]
  }
}

Every key that appears in all three products is required; discount is not, and because it is null once it gets the type list ["number", "null"]. price mixes 89 and 34.5, so it is a number, while stock is always whole and stays an integer. Every added value is a calendar date and every url a full web address, so they get date and uri formats. There are too few sku values for an enum.

How each part of the schema is inferred

  • Types: from every value at the same place. Mixed values get a type list such as ["string", "null"].
  • Objects: every key seen in any record becomes a property, in the order it first appears. With Keys in every record, a key is required only when no record lacks it.
  • Arrays: all items of all arrays at the same place are merged into one items schema, so an array of orders gets one schema for an order.
  • Enums: a text field with at most 8 different values over at least 20 values becomes an enum. With fewer samples there is not enough evidence, so none is added.
  • Formats: date-time, date, email or uri, only when every value of the field matches.

Options

Settings in the workspace that matter for this job
Option What it does
Enums for repeated text values Adds enum lists for low-cardinality text fields such as a status or a country code. Turn it off when the values you have are only a sample of the possible ones.
Formats Adds format for dates, date-times, email addresses and URIs when every value matches.
Required keys Keys in every record marks keys present in all records as required. None leaves required out entirely.
Use as document Replaces the source with the generated schema, as one step you can undo. Not offered on read-only shared links.

Limits

  • A generated schema describes the sample you give it, nothing more. It cannot know that status has a fourth value you have not seen yet, or that a missing key is an error. Review it and tighten it before you rely on it.
  • Ranges and lengths are not inferred: no minimum, maxLength or pattern. Objects do not get additionalProperties: false, so extra keys are allowed until you add it.
  • Numbers are typed from how they are written: 12 is an integer, 12.0 and 1e3 are numbers. A field with both becomes number.
  • When a key appears twice in one object, the last value is the one described, as most parsers keep only that one.
  • Values nested more than 100 levels deep are described by type only, with a $comment saying so.

Questions

Which JSON Schema version does it produce?
Draft 2020-12, the current version, declared in the schema's $schema keyword. Most validators that support 2019-09 or 2020-12 accept it, and simple schemas like these also work with draft 7 tools.
Why is a key I expected not required?
At least one record does not have it. JSON Mill marks a key required only when every object at that place has it. If the missing key is a data error, add it to required by hand, then check the data with the JSON Schema validator.
Does it change my numbers?
No. The generator never copies numbers into the schema; it only reads how each one is written to choose between integer and number. A 20-digit ID is still an integer, because it is written without a decimal point.
Can I generate TypeScript types or sample data instead?
Not yet. The generator writes JSON Schema only. Many tools turn a JSON Schema into types for TypeScript, Go or Python, so the schema is a useful first step.
Is my data uploaded?
No. JSON Mill processes your JSON in your browser, in a background worker on your device. Nothing leaves your device unless you choose to save or share a document, which needs an account, and JSON Mill tells you before it sends anything. How your data stays local explains how to check this yourself in your browser's developer tools.

Last updated