JSON Schema Generator

Generate a JSON Schema (Draft 07 or 2020-12) from any JSON document. Auto-detects formats (email, URI, UUID, date-time, IPv4). Smart array merging for optional fields. Use the output with Ajv, Python jsonschema, or any compatible validator.

Developer Tools
Ad
JSON input
JSON Schema

What this tool does

Paste a JSON document and get a JSON Schema describing its shape — types, required fields, recognized formats (email, URI, UUID, ISO date-time), and nested object structure. Use the schema as a starting point for runtime validation with Ajv (JavaScript), jsonschema (Python), Santhosh's jsonschema (Go), or any other Draft 7 / 2020-12-compatible validator.

Generation is one-directional: from data to schema. The schema describes what your sample LOOKS like, not what it MUST always look like. You'll often want to relax or tighten the generated rules (drop a field from required, add minimum/maximum, mark a number as integer-only) before committing the schema. Treat the output as a 90%-correct first draft.

JSON Schema in practice

A schema like the one this tool generates does three useful things in real systems:

  • Runtime validation — at API boundaries, reject malformed requests before they reach business logic. Ajv is the fastest JavaScript validator (faster than hand-rolled if-statements above ~10 fields).
  • OpenAPI specs — OpenAPI 3.0+ uses JSON Schema (with minor differences) for request/response bodies. Generated schemas plug into Swagger UI, Redoc, and code generators.
  • Editor autocompletion — VS Code can show suggestions and validate JSON/YAML files against a schema (via the $schema URL or settings). Helpful for config files like package.json, tsconfig.json, .eslintrc.

Draft 07 vs 2020-12

Draft 07 (2019) is the most widely supported — every JSON Schema library implements it well. Draft 2020-12 is the current edition, with some renames ($id, $defs) and new features (prefixItems, dependent schemas). For maximum compatibility, generate Draft 07. For greenfield projects using modern tooling, use 2020-12. The tool's output is functionally equivalent at this level of detail — just the $schema URL and a few keyword names differ.

Format detection

With "detect formats" enabled, strings that look like emails, URIs, UUIDs, ISO date-times, or dates get a "format" annotation. Note that format is advisory by default in JSON Schema — most validators won't enforce it unless you opt in. In Ajv, you pass {formats: require('ajv-formats')}; in Python's jsonschema, you pass format_checker=FormatChecker(). Without that opt-in, the format is documentation only.

What the inferrer can't know

  • Whether a field is truly optional. A field present in your single sample is marked required. To detect optional fields, use the JSON-to-TypeScript tool with multiple samples — or paste an array of objects here, in which case fields missing from any sample are correctly marked optional.
  • Allowed string values (enums). If your status is always one of "active" | "inactive" | "pending", the inferrer just sees "string". Add an enum: ["active", "inactive", "pending"] constraint by hand.
  • Numeric ranges. No way to know that age should be minimum: 0, maximum: 120 from sample data alone.
  • Integer vs float. JSON has no distinction; the schema says "type": "integer" only if every sample is a whole number. A single fractional value collapses the column to "number".
  • Nullable. A field that's null in your sample becomes "type": "null". If it can be either a string or null, you need to manually change to "type": ["string", "null"].

Validation workflow

// JavaScript with Ajv
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);
const validate = ajv.compile(schema);

if (!validate(data)) {
  console.log(validate.errors);  // [{ instancePath, keyword, message, ... }]
}

// Python with jsonschema
from jsonschema import validate, Draft7Validator
Draft7Validator(schema).validate(data)  // throws on error
errors = sorted(Draft7Validator(schema).iter_errors(data), key=lambda e: e.path)

Common use cases

Frequently asked questions

Draft 07 vs 2020-12 — which should I pick?

Draft 07 has the widest library support and is what most production systems use. Draft 2020-12 is the current edition with newer features (prefixItems, dependent schemas). For greenfield projects on modern tooling, 2020-12. For maximum compatibility, 07.

How are required fields determined?

For a single object input, every field is marked required. For an array of objects, the merge algorithm marks a field optional if it's missing from any sample. Provide a representative array of objects for accurate required-field detection.

Why is my number field "number" instead of "integer"?

JSON has no distinction. The inferrer marks <code>integer</code> only if every sample value is a whole number. One fractional sample collapses the field to <code>number</code>. Edit by hand if you know the API only sends integers.

How do I get format validation actually enforced?

The <code>format</code> keyword is advisory by default in most validators. In Ajv, install <code>ajv-formats</code> and pass it during construction. In Python's jsonschema, pass <code>format_checker=FormatChecker()</code>. Without opt-in, format is documentation-only.

Can it detect enums automatically?

No — and that's deliberate. Just because your sample has <code>"status": "active"</code> in every record doesn't mean "active" is the only valid value. Add <code>"enum": [...]</code> by hand once you know the full set.

Related tools