How to Generate JSON Schema from JSON: Step-by-Step Tutorial
This tutorial walks through generating a JSON Schema from real-world JSON data using the JSON Schema Generator. You will paste sample JSON, configure the inference settings, review the generated schema, and export to TypeScript and Zod.
π§ Open the tool to follow along:
Open JSON Schema GeneratorTable of Contents
1 Prepare Your JSON
Start with a representative JSON sample. The more complete the sample, the more accurate the inferred schema will be. For this tutorial, we will use a JSON array of user objects β a common API response shape:
[
{
"id": 1,
"name": "Alice Johnson",
"email": "[email protected]",
"role": "admin",
"active": true,
"created": "2025-01-15T09:30:00Z",
"tags": ["engineering", "leadership"]
},
{
"id": 2,
"name": "Bob Smith",
"email": null,
"role": "viewer",
"active": false,
"created": "2025-06-22T14:00:00Z"
}
]
Notice that the second object is missing the tags field and has email: null. These are the kinds of inconsistencies the generator handles automatically.
2 Paste or Load the JSON
Open the JSON Schema Generator and paste the JSON into the input area on the left. You can also drag-and-drop a .json file onto the drop zone, or click "browse" to pick a file from your disk.
As soon as valid JSON is detected, the validation indicator will show β Valid JSON and the schema will begin generating automatically.
π‘ Tip: Use the "Example JSONβ¦" dropdown to load one of the built-in samples if you want to explore the tool before using your own data.
3 Configure Inference Settings
The options bar at the top controls how the schema is inferred. For our tutorial JSON, set:
- Schema Draft: 2020-12 (the default and latest)
- Required Fields: "All present in sample" β this marks every key observed in the sample as required. Since
tagsis missing from item 2, it will not be in the required intersection. - Null Handling: "Treat null as nullable" β this makes the
emailfieldtype: ["string", "null"]since it is null in one item and a string in the other. - Array Mode: "Union of all items" β this merges both objects so all fields are included.
- Detect Formats: β
On β this will detect
emailformat on the email field anddate-timeformat on the created field.
The schema regenerates instantly whenever you change a setting.
4 Review the Generated Schema
The JSON Schema tab on the right shows the full schema. For our sample, you should see something like:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"email": { "type": ["string", "null"], "format": "email" },
"role": { "type": "string" },
"active": { "type": "boolean" },
"created": { "type": "string", "format": "date-time" },
"tags": { "type": "array", "items": { "type": "string" } }
},
"required": ["active", "created", "id", "name", "role"]
}
}
Key observations:
emailhas type["string", "null"]because it is null in one object and a string in the othertagsis absent fromrequiredbecause it only appears in the first object- The warnings panel will show: "Fields vary across objects: tags β required reduced to intersection"
emailhasformat: "email"andcreatedhasformat: "date-time"
5 Export to TypeScript, Zod, C#, or SQL
Click the TypeScript tab to see the generated type definition:
type Root = { id: number; name: string; email?: string | null; role: string; active: boolean; created: string; tags?: string[] }[];
Click the Zod tab for a runtime validation schema:
import { z } from "zod";
export const Root = z.array(z.object({
id: z.number().int(),
name: z.string(),
email: z.string().email().nullable().optional(),
role: z.string(),
active: z.boolean(),
created: z.string().datetime(),
tags: z.array(z.string()).optional(),
}));
The C# tab generates POCO classes and the SQL tab generates a CREATE TABLE statement. Use the Copy or Download buttons to export any output.
6 Handle Warnings and Edge Cases
Check the warnings panel below the tool for any issues the generator detected. Common warnings include:
- "Fields vary across objects" β some objects have keys that others don't. The required array uses the intersection of keys.
- "Mixed types detected" β a field has different types in different array items, so a union type is created.
- "Empty array encountered" β an empty array produces an
items: {}schema because no items could be inspected. - "Array sampled" β for arrays with more than 200 items, only the first 200 are inspected.
These warnings help you understand limitations of the inference and decide whether to adjust the schema manually.
Common Pitfalls
- Non-representative samples. If your JSON sample only shows the "happy path" (all fields present, no nulls), the schema will be too strict. Include edge cases in your sample.
- Overly strict required fields. The "all present" mode marks everything as required. If you are generating a schema for an API that sometimes omits optional fields, switch to "heuristic" or "none" mode.
- Format false positives. A short string that happens to look like a UUID might get flagged as uuid format. Toggle format detection off if this causes issues.
- SQL DDL limitations. The SQL export works best with flat objects. Deeply nested JSON produces
NVARCHAR(MAX)columns with a JSON comment β you will likely want to normalize the data before creating real tables.
π§ Try it yourself β paste any JSON and get a complete schema in seconds.
Open JSON Schema Generator