JSON → JSON Schema

Infer a JSON Schema from a sample document.

Private by design. Your input never leaves this browser. Conversions run locally on your device.

What this tool handles

  • Emits draft-07 or 2020-12.
  • Required lists the keys that appear in every observed object.
  • additionalProperties can be pinned to false.
  • Array items are merged across every element, so a mixed array gets a list of types.

Example

JSON sample

[{"id":1,"name":"Ada"},{"id":2,"name":"Linus"}]

JSON Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer"
      },
      "name": {
        "type": "string"
      }
    },
    "required": [
      "id",
      "name"
    ]
  }
}

When you would use it

  • Failing the build when a payload changes — Generate from a recorded request body, commit the schema, and validate against it with ajv or check-jsonschema in a pipeline step so a contract change is caught there instead of in an integration test.
  • An entry under components/schemas — OpenAPI 3.1 uses the 2020-12 dialect, so select that draft and delete the $schema line before pasting. For 3.0, a type array such as ["string", "null"] has to be rewritten using nullable.
  • Catching typos in a config file — Forbidding additional properties makes an unrecognised key an error rather than something quietly ignored, and it is applied to every object in the document, not only the outermost one.
  • Autocomplete while editing JSON by hand — Point an editor at the generated file through a $schema key or a workspace setting and it will complete property names and underline the ones that do not belong.

Common questions

How do I get a required list I can trust?

Feed it an array of records. A key is required when it was present in every object observed at that position, so a single sample makes all of its keys required simply because nothing contradicted them.

Does it infer format, enum or length constraints?

No. Every string is {"type": "string"} with no format, pattern, minLength or enum, and numbers get no minimum or maximum. An email, a UUID and an ISO timestamp are therefore indistinguishable in the output.

How is an array of mixed values typed?

Every element is taken into account, not just the first: [1, "a", null] produces "type": ["integer", "string", "null"], and a position that mixes objects with arrays produces an anyOf that is usually broader than the real contract.

What differs between the two drafts on offer?

Only the $schema URI. The same keywords are emitted either way — no prefixItems, no $defs and no $ref — and every nested schema is written out in place, so a shape repeated twice appears twice.

Related tools

  • JSON → TypeScript — Generate TypeScript interfaces or types from a JSON sample.
  • JSON → Zod — Generate a Zod schema from a JSON sample.
  • JSON → Python — Generate Python dataclasses from a JSON sample.
  • JSON → Go — Generate Go structs with json tags from a JSON sample.
  • JSON → SQL — Generate a CREATE TABLE statement from flat JSON rows.
  • Convert any format — Pick an input format and an output format and convert between any pair.

Browse all 25 tools