JSON to JSON Schema Generator
Paste one or more JSON samples to get their JSON Schema, see what OpenAI, Anthropic and Gemini structured outputs would reject (with the fix), and check any JSON against it. Nothing leaves your browser.
Key facts
- OpenAI’s strict mode needs every property listed in required and additionalProperties: false on every object; an optional field is written as a union with null.
Valid JSON, 374 B.
Required fields
JSON Schema version
More optionsenums, formats
Other keys in objects
Add to the schema
An enum is made when a text field has at most 5 different values and one repeats; a format (date-time, date, time, uuid, email, uri, ipv4) only when every value matches it.
JSON Schema from 3 samples
14fields
12 required, 2 optional, 1 can be null. Gemini takes it as it is; OpenAI needs 6 changes, Anthropic needs 3 changes, all made for you.
Structured outputs (dots in the tree: OpenAI)
- Size
- 1.4 KB · ~199 tokens
- Formats
- date-time, email, uri
- Draft
- 2020-12
The JSON Schema1.4 KB, 793 B minified · 2020-12
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"customer": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phone": {
"type": "string"
}
},
"required": [
"name",
"email"
]
},
"priority": {
"type": "string",
"enum": [
"high",
"low"
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"summary": {
"type": "string"
},
"order_total": {
"type": "number"
},
"assignee": {
"type": [
"string",
"null"
]
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"size_kb": {
"type": "integer"
}
},
"required": [
"url",
"size_kb"
]
}
}
},
"required": [
"id",
"created_at",
"customer",
"priority",
"tags",
"summary",
"assignee",
"attachments"
]
}Structured outputs: OpenAI, Anthropic, GeminiWhat each would reject or ignore, and the fixed schema
OpenAI strict mode: 6 changes, all made for you below.
For response_format (text.format) of type json_schema, or a function, with strict: true.
$additionalPropertiesRejectedOpenAI needs additionalProperties: false on every object.
Fix: Set it to false.
$.customeradditionalPropertiesRejectedOpenAI needs additionalProperties: false on every object.
Fix: Set it to false.
$.customer.phonerequiredRejectedOptional, but OpenAI needs every property listed in required.
Fix: Made it required and nullable: the model sends null when there’s no value.
$.order_totalrequiredRejectedOptional, but OpenAI needs every property listed in required.
Fix: Made it required and nullable: the model sends null when there’s no value.
$.attachments[]additionalPropertiesRejectedOpenAI needs additionalProperties: false on every object.
Fix: Set it to false.
$.attachments[].urlformatNot supportedOpenAI supports these formats only: date-time, time, date, duration, email, hostname, ipv4, ipv6, uuid.
Fix: Removed it and added {format: "uri"} to the description, so the model still sees it.
- Properties in all
- 14 of 5,000
- Levels of nesting
- 2 of 10
- Enum values in all
- 2 of 1,000
- Characters in names and enum values
- 100 of 120,000
The schema for OpenAI
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"customer": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
},
"phone": {
"type": [
"string",
"null"
]
}
},
"required": [
"name",
"email",
"phone"
],
"additionalProperties": false
},
"priority": {
"type": "string",
"enum": [
"high",
"low"
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"summary": {
"type": "string"
},
"order_total": {
"type": [
"number",
"null"
]
},
"assignee": {
"type": [
"string",
"null"
]
},
"attachments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "{format: \"uri\"}"
},
"size_kb": {
"type": "integer"
}
},
"required": [
"url",
"size_kb"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"created_at",
"customer",
"priority",
"tags",
"summary",
"order_total",
"assignee",
"attachments"
],
"additionalProperties": false
}Fine-tuned models also reject minLength, maxLength, pattern, format, minimum, maximum, multipleOf, patternProperties, minItems and maxItems. Rules from OpenAI’s documentation, checked Oct 25, 2026.
As TypeScript, Zod or PydanticTypes and validators written from the schema
export type Root = {
id: string;
created_at: string;
customer: {
name: string;
email: string;
phone?: string;
};
priority: "high" | "low";
tags: string[];
summary: string;
order_total?: number;
assignee: string | null;
attachments: {
url: string;
size_kb: number;
}[];
};
TypeScript describes the shape only: formats, patterns and number limits need a validator such as the Zod version.
How this works: Method, 8 sources, Checked against 5 worked examples,
How this works
Method
The samples are merged position by position. A property is required when every object at its place has it (or always, or never, as you choose); one that is sometimes null becomes nullable; a string gets a format only when every value passes that format’s RFC check, and an enum when it has at most 5 values and one repeats. Each provider check compares every keyword with that provider’s documented list and limits, and fixes what it can the way OpenAI’s and Anthropic’s own SDKs do. JSON is checked by our own validator for drafts 2020-12 and 07.
Sources
- JSON Schema Validation: A Vocabulary for Structural Validation of JSON (draft 2020-12)
- JSON Schema: A Media Type for Describing JSON Documents (draft 2020-12)
- RFC 3339: Date and Time on the Internet: Timestamps (IETF, 2002)
- Structured model outputs: Supported schemas (OpenAI, checked 2026-10-25)
- Structured outputs: JSON Schema limitations (Anthropic, checked 2026-10-25)
- Structured outputs: JSON schema support (Google, checked 2026-10-25)
- openai-python: to_strict_json_schema (src/openai/lib/_pydantic.py) (OpenAI)
- anthropic-sdk-python: transform_schema (src/anthropic/lib/_parse/_transform.py) (Anthropic)
How it’s tested
5 worked examples for this page are checked by automated tests before every release: given the inputs, the tool must show the expected answer.
Privacy
On your device. Nothing you enter or open leaves this browser. About privacy labels
Changes
- First published.
Frequently Asked Questions
How do I turn JSON into a JSON Schema?
Paste a JSON sample in the box: the schema appears beside it as you type, as a tree and as JSON you can copy or download. Add more samples with "Add sample" (or paste JSON Lines, one record per line) and they are merged: a field missing from one of them becomes optional, a field that was null somewhere becomes nullable, and a string with a few repeated values becomes an enum.
How does it decide which fields are required?
By default a field is required when it appears in every sample (and, inside arrays, in every item). With one sample everything it has is required, so add a second sample that leaves out the optional fields, or choose "All" or "None" under Required fields.
What does OpenAI strict mode need from a schema?
OpenAI’s docs list three rules that catch most schemas: the root must be an object (not anyOf), every object needs additionalProperties: false, and every property must be listed in required, with optional ones written as a union with null. allOf, not, if/then/else, dependentRequired and dependentSchemas are not supported, and only nine string formats are (uri isn’t one). The Structured outputs section lists what your schema breaks and gives the fixed schema.
Can I use the schema as a Claude tool input_schema?
Yes. A tool’s input_schema must be an object. With strict: true, Anthropic also needs additionalProperties: false on every object and rejects numeric constraints (minimum, maximum, multipleOf), minLength and maxLength, minItems above 1 and recursive schemas, and a request can have at most 24 optional parameters and 16 with union types across its strict schemas. The fixed schema moves the constraints it removes into the description, as Anthropic’s SDK does.
Does Gemini accept JSON Schema?
Yes: Gemini’s structured output takes a JSON Schema subset with types, properties, required, additionalProperties, enum, format, minimum and maximum, items, prefixItems, minItems and maxItems, anyOf and $ref. It accepts minLength, maxLength, uniqueItems and a few others without enforcing them (the API strips them), so check those in your own code. responseSchema and responseJsonSchema are deprecated in favour of response_format.
How do I validate JSON against a schema?
Paste the JSON in "Check JSON against the schema". Each problem shows where it is, such as $.attachments[0].size_kb, and what was expected, and tapping the path selects it in the box. It checks drafts 2020-12 and 07, formats included; if a schema uses a keyword the checker doesn’t cover, such as unevaluatedProperties, it says so instead of passing it silently. To check against your own schema, choose "From a schema" at the top.
Draft 2020-12 or draft-07?
2020-12 is the current version and what OpenAI, Anthropic and Gemini read. Pick draft-07 for older validators and tools that only know it. For the schemas this tool writes the two differ only in the $schema line.
Is my JSON uploaded anywhere?
No. The schema, the checks and the code are worked out in your browser, and nothing you paste is sent or saved. The page’s address holds only your options, so a copied link never carries your data.
OpenAI, Anthropic, Claude and Gemini are trademarks of their owners. Binary Decimal isn’t affiliated with them; the names only say which documented rules each check follows.