json

FormatValidateConvert

JSON to JSON Schema

JSON
Language
Structured output

Result· read-only

—JSON Schema

The result appears here.

Generate

JSON to JSON Schema: generate a schema from a sample.

Your document never leaves the browser.

A JSON Schema inferred from your sample — 2020-12 or draft-07, never uploaded.

Writing a schema by hand for a large payload is slow and error-prone. Paste an example document instead and start from a schema that already accepts it, then tighten the parts you know more about than the sample does.

2020-12

the default draft; draft-07 is one choice away

false

additionalProperties, so an unknown key is an error

0

bytes leave your machine

How the sample is described

Each distinct object shape becomes an entry under $defs, named as the other languages name their types, and the root is a $ref to its own entry. A key goes in required when every record that could hold it does, so sku, qty, price and note are required on Item, and gift-wrap is not.

Numbers are split the way JSON Schema can split them: qty never has a fraction, so it is integer, while price holds 3.5 and is number. note is null in one line item and text in the other, so its type is the array ["null", "string"]. Every object closes with additionalProperties: false, so a key the sample never had is reported as an error.

1

The sample, an order with two line items, pasted as the source

{
  "order_id": 1042,
  "placed_at": "2026-09-25T10:15:00Z",
  "paid": true,
  "customer": { "name": "Ada Lovelace", "email": "ada@example.com" },
  "items": [
    { "sku": "PEN-01", "qty": 2, "price": 3.5, "note": null },
    { "sku": "INK-07", "qty": 1, "price": 12, "note": "Fragile", "gift-wrap": true }
  ]
}
2

The 2020-12 schema written for it

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$ref": "#/$defs/Root",
  "$defs": {
    "Customer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "email"
      ],
      "additionalProperties": false
    },
    "Item": {
      "type": "object",
      "properties": {
        "sku": {
          "type": "string"
        },
        "qty": {
          "type": "integer"
        },
        "price": {
          "type": "number"
        },
        "note": {
          "type": [
            "null",
            "string"
          ]
        },
        "gift-wrap": {
          "type": "boolean"
        }
      },
      "required": [
        "sku",
        "qty",
        "price",
        "note"
      ],
      "additionalProperties": false
    },
    "Root": {
      "type": "object",
      "properties": {
        "order_id": {
          "type": "integer"
        },
        "placed_at": {
          "type": "string"
        },
        "paid": {
          "type": "boolean"
        },
        "customer": {
          "$ref": "#/$defs/Customer"
        },
        "items": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Item"
          }
        }
      },
      "required": [
        "order_id",
        "placed_at",
        "paid",
        "customer",
        "items"
      ],
      "additionalProperties": false
    }
  }
}

Two options

1

A user nested in the root

{ "user": { "id": 7 } }
2

With Draft draft-07 and allow extra properties on

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "#/definitions/Root",
  "definitions": {
    "User": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": true
    },
    "Root": {
      "type": "object",
      "properties": {
        "user": {
          "$ref": "#/definitions/User"
        }
      },
      "required": [
        "user"
      ],
      "additionalProperties": true
    }
  }
}

Option

Draft

Draft: 2020-12, the default, with its definitions under $defs, or draft-07, with them under definitions, for validators and tools that stop at the older draft.

Option

allow extra properties

allow extra properties: off by default. Turn it on to write additionalProperties: true, for payloads that are allowed to grow new keys without failing validation.

From a sample to a contract

An inferred schema is a starting point, not a specification. It cannot know that qty must be at least 1, that email follows a format, or that a status only takes three values. Add minimum, format, pattern and enum where they apply, and give fields a description while you are there.

To test the result, open the JSON Schema Validator, paste the schema beside another document, and every violation is listed with its path. A second real example is the quickest way to find a key the first one did not show optional enough.

1

A quantity, an email and a status

{ "qty": 1, "email": "ada@example.com", "status": "paid" }
2

The schema accepts them, and says nothing more about them

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$ref": "#/$defs/Root",
  "$defs": {
    "Root": {
      "type": "object",
      "properties": {
        "qty": {
          "type": "integer"
        },
        "email": {
          "type": "string"
        },
        "status": {
          "type": "string"
        }
      },
      "required": [
        "qty",
        "email",
        "status"
      ],
      "additionalProperties": false
    }
  }
}

Your sample stays here

Inference and code generation both run inside this browser tab. The sample is never uploaded, stored on a server or logged, because the page has no server to send it to, and once loaded it carries on working with the connection off.

Read next:

FAQ

Frequently asked questions

Didn’t find your answer?Write to us on the contact page →
Which draft should I choose?

The 2020-12 draft, unless a tool you depend on only reads draft-07. OpenAPI 3.1 uses 2020-12; many older validators and editors expect draft-07.

Is this the same as the schema for OpenAI, Claude or Gemini?

No. Those three follow each provider’s own rules, such as which keys must be required, and have pages of their own.

Can it infer enums or string formats?

No. One sample cannot tell a fixed list of values from free text, so strings stay string. Add enum and format yourself.

Keyboard shortcuts

Send feedback

Questions, bug reports and feature requests are all welcome. A bug report is easiest to act on with the shape of the document that caused it — never send anything confidential.

Email us

Contact page, in a new tab, so this page stays as it is.

Settings

Indent

The result is written with it — YAML and XML at 2 spaces when it is Tab.

Code text size
14 px

Both panes.

Wrap long lines

Load from a URL

Your browser fetches it directly — the request goes to that site, never to us.