DevToolBoxฟรี
บล็อก

JSON to JSON Schema: Complete Guide to Generating Schemas from JSON Data

14 min readโดย DevToolBox

TL;DR

JSON Schema is a vocabulary that lets you validate, annotate, and describe the structure of JSON data. You can generate JSON Schema from JSON automatically using online converters like our JSON to JSON Schema tool, CLI tools like quicktype, or libraries in Python (genson) and JavaScript (to-json-schema). This guide covers the conversion algorithm, all major methods, schema customization, Draft 2020-12 vs Draft-07 differences, validation with Ajv, and real-world use cases.

Key Takeaways

  • JSON Schema describes JSON structure using keywords like type, properties, required, and additionalProperties.
  • Automatic schema generation infers types from sample data; always review and add constraints like minimum, maxLength, and pattern.
  • Draft 2020-12 is the latest specification; Draft-07 remains the most widely supported in tooling.
  • Ajv (JavaScript) and jsonschema (Python) are the leading validation libraries for enforcing schemas at runtime.
  • Real-world use cases include API contract validation, configuration file checking, form generation, and OpenAPI specification authoring.
  • Use our free JSON Schema Generator to produce schemas instantly from any JSON input.

What Is JSON Schema?

JSON Schema is a declarative language that allows you to define the expected structure, data types, and constraints for JSON documents. Written in JSON itself, a schema acts as a contract between data producers and consumers. It specifies which fields are required, what types they should be, whether additional properties are allowed, and what validation rules apply to each value.

The specification is maintained by the JSON Schema organization and has gone through several drafts, with Draft 2020-12 being the most recent stable release. Earlier versions such as Draft-07 and Draft-04 are still widely used in production systems. JSON Schema powers tools across every major programming language, from API documentation generators like OpenAPI and Swagger to form builders, configuration validators, and code generators.

A simple example: given a JSON object representing a user, a JSON Schema might declare that name must be a string, age must be a non-negative integer, and email must match an email format pattern. Any JSON document can then be validated against this schema to ensure it meets the specified requirements before being processed.

Why Generate JSON Schema from JSON?

Writing JSON Schema by hand is tedious and error-prone, especially for complex or deeply nested structures. Generating a schema automatically from existing JSON samples offers several advantages:

  • Speed: Convert a 200-field API response into a schema in seconds rather than hours of manual typing.
  • Accuracy: Automated tools correctly identify nested objects, arrays of mixed types, and nullable fields that humans might miss.
  • Bootstrapping: Use generated schemas as a starting point, then refine with business-specific constraints like minimum, maximum, pattern, and enum.
  • Documentation: Schemas generated from real data serve as living documentation for APIs and data formats.
  • Testing: Quickly generate schemas from fixture data to use in integration tests and contract testing.

Whether you are building an API, validating configuration files, or generating forms from data models, starting with an automatically generated schema from actual JSON saves significant development time. For related type generation workflows, see our guides on JSON to TypeScript and JSON Schema validation.

How JSON-to-Schema Conversion Works

The conversion algorithm traverses a JSON document recursively and builds a corresponding schema tree. Here is a high-level breakdown of the process:

  1. Type inference: For each value, the algorithm determines the JSON type (string, number, integer, boolean, null, object, or array).
  2. Object handling: For objects, the algorithm iterates over all keys, recursively infers the schema for each value, and records them under properties. All observed keys are typically added to the required array.
  3. Array handling: For arrays, the algorithm inspects all elements. If all elements share the same type, a single items schema is produced. If elements have different types, a oneOf or tuple-style prefixItems is used.
  4. Number differentiation: Numbers without decimal parts are typed as integer; those with decimals are typed as number.
  5. Null merging: When a field is null in the sample data, advanced generators produce a union type like {"type": ["string", "null"]} or a oneOf with a null branch.
  6. Schema assembly: The root schema object is assembled with $schema (the meta-schema URI), type, and the inferred properties or items.

Here is a concrete example of the input and output:

JSON Input:

{
  "id": 1,
  "name": "Widget",
  "price": 9.99,
  "in_stock": true,
  "tags": ["electronics", "sale"],
  "dimensions": {
    "width": 10,
    "height": 5,
    "unit": "cm"
  }
}

Generated JSON Schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "name": { "type": "string" },
    "price": { "type": "number" },
    "in_stock": { "type": "boolean" },
    "tags": {
      "type": "array",
      "items": { "type": "string" }
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "width": { "type": "integer" },
        "height": { "type": "integer" },
        "unit": { "type": "string" }
      },
      "required": ["width", "height", "unit"]
    }
  },
  "required": ["id", "name", "price", "in_stock", "tags", "dimensions"]
}

The algorithm correctly identifies id as an integer, price as a number, tags as an array of strings, and dimensions as a nested object with its own required properties.

Method 1: Online JSON to JSON Schema Converter

The fastest way to generate a JSON Schema is to use an online converter. Our JSON to JSON Schema tool provides instant conversion with these features:

  • Paste any valid JSON and receive a complete schema immediately.
  • Choose between Draft 2020-12, Draft-07, and Draft-04 output.
  • Toggle whether all properties should be marked as required.
  • Option to set additionalProperties: false for strict validation.
  • Copy the generated schema with one click.

For a more advanced schema authoring experience with title and description fields, try the JSON Schema Generator tool which allows you to add metadata annotations directly.

Online converters are ideal for quick one-off conversions, exploring JSON structures during development, and generating initial schemas that you refine by hand afterward.

Method 2: Using quicktype CLI

quicktype is a powerful command-line tool that generates types and schemas from JSON, JSON Schema, TypeScript, and GraphQL. It supports over 20 output languages and can produce JSON Schema from JSON samples.

Installation:

npm install -g quicktype

Generate JSON Schema from a JSON file:

# From a local JSON file
quicktype -s json -o schema.json --lang schema data.json

# From a URL
quicktype -s json -o schema.json --lang schema \
  "https://api.example.com/users/1"

# From stdin
echo '{"name":"Alice","age":30}' | quicktype -s json -o schema.json --lang schema

Example output for a user object:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$ref": "#/definitions/User",
  "definitions": {
    "User": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": { "type": "string" },
        "age": { "type": "integer" }
      },
      "required": ["age", "name"],
      "title": "User"
    }
  }
}

quicktype excels when you have multiple JSON samples and want to merge them into a single schema that covers all observed variations. You can pass multiple files and quicktype will compute the union of all properties, automatically using optional fields where appropriate.

Method 3: Python with genson Library

The genson library is the standard Python tool for generating JSON Schema from JSON instances. It is particularly useful when you need to process schemas programmatically or integrate generation into a Python pipeline.

Installation:

pip install genson

Basic usage:

from genson import SchemaBuilder
import json

# Sample JSON data
data = {
    "id": 1,
    "name": "Widget",
    "price": 9.99,
    "in_stock": True,
    "tags": ["electronics", "sale"],
    "dimensions": {
        "width": 10,
        "height": 5,
        "unit": "cm"
    }
}

# Build schema
builder = SchemaBuilder()
builder.add_object(data)

# Get the schema
schema = builder.to_schema()
print(json.dumps(schema, indent=2))

Merging multiple samples:

from genson import SchemaBuilder
import json

builder = SchemaBuilder()

# Add multiple JSON instances to capture all possible fields
samples = [
    {"name": "Alice", "age": 30, "email": "alice@example.com"},
    {"name": "Bob", "age": 25, "phone": "+1234567890"},
    {"name": "Charlie", "age": None, "email": "charlie@test.com"},
]

for sample in samples:
    builder.add_object(sample)

schema = builder.to_schema()
print(json.dumps(schema, indent=2))
# Result: "age" allows integer and null,
# "email" and "phone" are optional (not in required)

The key advantage of genson is its ability to merge multiple samples. By feeding it several real API responses, you get a schema that accurately represents the full range of possible data shapes, including optional fields and nullable values.

Method 4: JavaScript/Node.js with to-json-schema

For JavaScript and Node.js projects, the to-json-schema package provides a straightforward conversion from JSON values to JSON Schema.

Installation:

npm install to-json-schema

Basic usage:

const toJsonSchema = require('to-json-schema');

const data = {
  id: 1,
  name: "Widget",
  price: 9.99,
  inStock: true,
  tags: ["electronics", "sale"],
  dimensions: {
    width: 10,
    height: 5,
    unit: "cm"
  }
};

const schema = toJsonSchema(data);
console.log(JSON.stringify(schema, null, 2));

With configuration options:

const toJsonSchema = require('to-json-schema');

const data = {
  name: "Alice",
  email: "alice@example.com",
  created_at: "2026-01-15T10:30:00Z",
  score: 95.5
};

const schema = toJsonSchema(data, {
  required: true,            // mark all properties required
  postProcessFnc: (type, schema, value, defaultFnc) => {
    // Detect date-time strings
    if (type === 'string' &&
        typeof value === 'string' &&
        /^\d{4}-\d{2}-\d{2}T/.test(value)) {
      schema.format = 'date-time';
    }
    return schema;
  }
});

console.log(JSON.stringify(schema, null, 2));

The to-json-schema package is lightweight and works in both Node.js and browser environments, making it suitable for client-side schema generation in web applications.

For an alternative approach that generates runtime validators instead of schemas, see our guide on JSON to Zod Schema.

Understanding the Generated Schema

Whether you use an online tool, CLI, or library, the generated schema uses a standard set of JSON Schema keywords. Understanding these keywords is essential for reviewing and customizing the output.

KeywordPurposeExample
typeDeclares the expected data type"type": "string"
propertiesDefines sub-schemas for each object key"properties": {"name": {"type": "string"}}
requiredLists which properties must be present"required": ["id", "name"]
additionalPropertiesControls whether extra keys are allowed"additionalProperties": false
itemsDefines the schema for array elements"items": {"type": "string"}
$refReferences a reusable schema definition"$ref": "#/$defs/Address"
$defsContainer for reusable sub-schemas"$defs": {"Address": {...}}

When reviewing generated schemas, pay attention to the required array. Automatic generators mark all observed properties as required because they appear in the sample. In practice, some fields may be optional in your actual data model. Similarly, additionalProperties defaults to true (allowing any extra fields) unless explicitly set to false.

Customizing Generated Schemas

Auto-generated schemas provide the structural skeleton, but production-grade schemas need business-specific constraints. Here are the most common customizations:

Adding numeric constraints:

{
  "type": "object",
  "properties": {
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "price": {
      "type": "number",
      "minimum": 0,
      "exclusiveMinimum": 0,
      "multipleOf": 0.01
    },
    "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000
    }
  }
}

String constraints and patterns:

{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "maxLength": 254
    },
    "phone": {
      "type": "string",
      "pattern": "^\\+[1-9]\\d{1,14}$"
    },
    "slug": {
      "type": "string",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
      "minLength": 1,
      "maxLength": 100
    },
    "status": {
      "type": "string",
      "enum": ["active", "inactive", "pending", "archived"]
    }
  }
}

Array constraints:

{
  "type": "object",
  "properties": {
    "tags": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 },
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true
    },
    "coordinates": {
      "type": "array",
      "prefixItems": [
        { "type": "number", "minimum": -180, "maximum": 180 },
        { "type": "number", "minimum": -90, "maximum": 90 }
      ],
      "items": false,
      "minItems": 2,
      "maxItems": 2
    }
  }
}

Conditional schemas with if/then/else:

{
  "type": "object",
  "properties": {
    "payment_method": {
      "type": "string",
      "enum": ["credit_card", "bank_transfer", "paypal"]
    }
  },
  "if": {
    "properties": {
      "payment_method": { "const": "credit_card" }
    }
  },
  "then": {
    "required": ["card_number", "expiry_date", "cvv"]
  },
  "else": {
    "if": {
      "properties": {
        "payment_method": { "const": "bank_transfer" }
      }
    },
    "then": {
      "required": ["bank_name", "account_number"]
    }
  }
}

The key takeaway is that generated schemas provide an excellent starting point, but they should always be refined with domain-specific constraints before being used in production. For a complete reference on available keywords, check our JSON Schema complete guide.

Draft 2020-12 vs Draft-07 Differences

The two most commonly used JSON Schema versions are Draft 2020-12 (latest) and Draft-07 (most widely supported). Understanding their differences is important when choosing which to target.

FeatureDraft-07Draft 2020-12
Meta-schema URIhttp://json-schema.org/draft-07/schema#https://json-schema.org/draft/2020-12/schema
Definitions keyworddefinitions$defs
Tuple validationitems (array of schemas)prefixItems + items (boolean or schema)
Dynamic referencesNot supported$dynamicRef / $dynamicAnchor
Vocabulary systemNot supported$vocabulary for extensibility
if/then/elseSupportedSupported
Tooling supportExcellent (broadest support)Good and growing

Recommendation: Use Draft 2020-12 for new projects where your toolchain supports it. Fall back to Draft-07 when you need maximum compatibility, especially with OpenAPI 3.0 (which uses a modified subset of Draft-07). Our JSON to JSON Schema converter supports both drafts.

Validating Data Against Your Schema

Generating a schema is only half the story. The real value comes from using that schema to validate data at runtime, in CI pipelines, or at API boundaries.

JavaScript/TypeScript with Ajv (the fastest JSON Schema validator):

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);

const schema = {
  type: 'object',
  properties: {
    id: { type: 'integer' },
    name: { type: 'string', minLength: 1 },
    email: { type: 'string', format: 'email' },
    age: { type: 'integer', minimum: 0, maximum: 150 },
    tags: {
      type: 'array',
      items: { type: 'string' },
      uniqueItems: true
    }
  },
  required: ['id', 'name', 'email'],
  additionalProperties: false
};

const validate = ajv.compile(schema);

// Valid data
const validData = {
  id: 1,
  name: 'Alice',
  email: 'alice@example.com',
  age: 30,
  tags: ['admin']
};
console.log(validate(validData)); // true

// Invalid data
const invalidData = {
  id: 'not-a-number',
  name: '',
  email: 'invalid-email',
  age: -5,
  extra_field: 'not allowed'
};
console.log(validate(invalidData)); // false
console.log(validate.errors);
// Returns detailed error objects for each violation

Python with jsonschema library:

from jsonschema import validate, ValidationError, Draft202012Validator
import json

schema = {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "id": {"type": "integer"},
        "name": {"type": "string", "minLength": 1},
        "email": {"type": "string", "format": "email"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["id", "name", "email"],
    "additionalProperties": False
}

# Validate a single document
data = {"id": 1, "name": "Alice", "email": "alice@example.com"}
validate(instance=data, schema=schema)  # Passes silently

# Collect all errors
validator = Draft202012Validator(schema)
invalid_data = {"id": "bad", "name": "", "extra": True}
errors = list(validator.iter_errors(invalid_data))
for error in sorted(errors, key=lambda e: list(e.path)):
    print(f"{list(error.path)}: {error.message}")

Integration patterns:

  • API middleware: Validate request bodies against schemas before they reach your route handlers. Express.js libraries like express-json-validator-middleware or fastify's built-in schema support make this easy.
  • CI/CD pipelines: Validate configuration files (package.json, tsconfig.json, docker-compose.yml) against their schemas during build steps.
  • Contract testing: Use schemas as contracts in consumer-driven contract testing between microservices.

Real-World Use Cases

JSON Schema is used across the software development lifecycle. Here are the most impactful applications:

1. API Documentation with OpenAPI/Swagger

OpenAPI 3.x uses JSON Schema (Draft-07 subset) to describe request bodies, response payloads, query parameters, and headers. Generating schemas from sample API responses gives you a head start on writing OpenAPI specifications. Tools like Swagger UI then render interactive documentation from these schemas.

2. Configuration File Validation

Many tools use JSON Schema to validate their configuration files: package.json, tsconfig.json, .eslintrc.json, VS Code settings.json, and GitHub Actions workflow files all have published JSON Schemas. IDEs like VS Code use these schemas to provide autocompletion and inline validation as you edit.

3. Form Generation

Libraries like react-jsonschema-form, Formily, and Ajv + JSON Forms render HTML forms directly from JSON Schema definitions. Each schema property becomes a form field with the correct input type, validation rules, and error messages. This is particularly powerful for dynamic forms where the structure comes from a backend API.

4. Code Generation

JSON Schema serves as the input for code generators that produce typed data classes in various languages. Tools like jsonschema2pojo (Java), quicktype (multi-language), and json-schema-to-typescript convert schemas into language-specific types. This is the reverse of what we covered earlier: schema from JSON, then code from schema.

5. Data Pipeline Validation

In ETL pipelines and data engineering, JSON Schema validates incoming data before it enters a data warehouse or processing pipeline. This catches malformed records early, preventing downstream errors and data corruption.

For more on how to work with JSON data transformations, see our guides on JSON formatting and validation and JSON to CSV conversion.

Advanced: Schema Composition with allOf, anyOf, oneOf

JSON Schema supports powerful composition keywords that let you combine multiple schemas:

{
  "type": "object",
  "properties": {
    "id": { "type": "integer" },
    "type": { "type": "string", "enum": ["personal", "business"] }
  },
  "required": ["id", "type"],
  "allOf": [
    {
      "if": {
        "properties": { "type": { "const": "personal" } }
      },
      "then": {
        "properties": {
          "first_name": { "type": "string" },
          "last_name": { "type": "string" },
          "date_of_birth": { "type": "string", "format": "date" }
        },
        "required": ["first_name", "last_name"]
      }
    },
    {
      "if": {
        "properties": { "type": { "const": "business" } }
      },
      "then": {
        "properties": {
          "company_name": { "type": "string" },
          "tax_id": { "type": "string" },
          "industry": { "type": "string" }
        },
        "required": ["company_name", "tax_id"]
      }
    }
  ]
}

Composition keywords explained:

  • allOf: Data must be valid against ALL listed schemas (intersection).
  • anyOf: Data must be valid against at least ONE schema (union).
  • oneOf: Data must be valid against EXACTLY ONE schema (discriminated union).
  • not: Data must NOT be valid against the given schema.

These keywords are essential for modeling polymorphic data structures, discriminated unions, and conditional validation rules that go beyond what automatic generation can produce.

Frequently Asked Questions

What is the easiest way to generate JSON Schema from JSON?

The easiest way is to use an online converter. Paste your JSON into a tool like our JSON to JSON Schema converter and get the schema instantly. No installation or coding required. For programmatic use, Python developers can use the genson library and JavaScript developers can use to-json-schema, both requiring just a few lines of code.

What is the difference between JSON Schema Draft-07 and Draft 2020-12?

Draft 2020-12 introduces $defs (replacing definitions), prefixItems for tuple validation (replacing the overloaded items array syntax), $dynamicRef for dynamic references, and the $vocabulary system for extensibility. Draft-07 has broader tooling support, especially in the OpenAPI ecosystem. Choose Draft 2020-12 for new projects and Draft-07 when maximum compatibility is needed.

Can I validate JSON against a schema in the browser?

Yes. Ajv is fully compatible with browsers and can be bundled with any JavaScript framework. You can also use ajv-formats for format validation (email, URI, date-time). For React applications, react-jsonschema-form uses Ajv internally to validate form data against schemas in real time.

How do I handle nullable fields in JSON Schema?

In Draft 2020-12, use a type array: "type": ["string", "null"]. In Draft-07, you can also use oneOf: "oneOf": [{"type": "string"}, {"type": "null"}]. Most automatic generators detect null values in sample data and produce the correct nullable type declaration.

What is additionalProperties and should I set it to false?

The additionalProperties keyword controls whether an object can have properties not listed in properties. When set to false, any extra keys cause validation failure. Set it to false for strict API contracts where unexpected fields indicate a problem. Leave it as true (default) for extensible formats where consumers should ignore unknown fields.

How does JSON Schema relate to TypeScript types?

JSON Schema validates data at runtime while TypeScript types are checked at compile time. They are complementary: use JSON Schema to validate incoming API data, then use TypeScript interfaces for type-safe processing. Tools like json-schema-to-typescript can generate TypeScript interfaces from JSON Schema, and conversely, tools can generate JSON Schema from TypeScript types using ts-json-schema-generator. See our JSON to TypeScript guide for more.

Conclusion

Generating JSON Schema from JSON is one of the most practical skills in modern web development. Whether you need to validate API responses, document data contracts, generate forms, or enforce configuration file structure, JSON Schema provides a standardized, language-agnostic solution.

Start by generating a schema automatically from your JSON data using our JSON to JSON Schema converter or the JSON Schema Generator. Then refine the output by adding constraints, patterns, enums, and conditional logic. Finally, integrate validation into your application using Ajv (JavaScript) or jsonschema (Python) to enforce your schema at runtime.

For related workflows, explore JSON Schema validation best practices, JSON to TypeScript conversion, and JSON to Zod Schema for runtime validation.

𝕏 Twitterin LinkedIn
บทความนี้มีประโยชน์ไหม?

อัปเดตข่าวสาร

รับเคล็ดลับการพัฒนาและเครื่องมือใหม่ทุกสัปดาห์

ไม่มีสแปม ยกเลิกได้ตลอดเวลา

ลองเครื่องมือที่เกี่ยวข้อง

JSJSON to JSON Schema Generator{S}JSON Schema Generator{ }JSON FormatterJSON Validator

บทความที่เกี่ยวข้อง

การตรวจสอบ JSON Schema: ประเภท เครื่องมือ และแนวทางปฏิบัติที่ดี

ทุกอย่างเกี่ยวกับการตรวจสอบ JSON Schema: ตั้งแต่ประเภทพื้นฐานไปจนถึงรูปแบบขั้นสูง ไลบรารีตรวจสอบ และการผสานกับ TypeScript และ API

JSON เป็น TypeScript: คู่มือฉบับสมบูรณ์พร้อมตัวอย่าง

เรียนรู้วิธีแปลงข้อมูล JSON เป็น interface ของ TypeScript โดยอัตโนมัติ ครอบคลุม nested objects, arrays, optional fields และแนวทางปฏิบัติที่ดี