Skip to content

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.

v2026.10.25

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.

RootobjectOpenAI: OpenAI needs additionalProperties: false on every object.
  • idstringrequired
  • created_atstringrequireddate-time
  • customerobjectrequiredOpenAI: OpenAI needs additionalProperties: false on every object.
    • namestringrequired
    • emailstringrequiredemail
    • phonestringoptionalOpenAI: Optional, but OpenAI needs every property listed in required.
  • prioritystringrequired
    "high""low"
  • tagsstring[]required
  • summarystringrequired
  • order_totalnumberoptionalOpenAI: Optional, but OpenAI needs every property listed in required.
  • assigneestringrequiredor null
  • attachmentsobject[]requiredOpenAI: OpenAI needs additionalProperties: false on every object.
    • urlstringrequireduriOpenAI: OpenAI supports these formats only: date-time, time, date, duration, email, hostname, ipv4, ipv6, uuid.
    • size_kbintegerrequired

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.

  • $additionalPropertiesRejected

    OpenAI needs additionalProperties: false on every object.

    Fix: Set it to false.

  • $.customeradditionalPropertiesRejected

    OpenAI needs additionalProperties: false on every object.

    Fix: Set it to false.

  • $.customer.phonerequiredRejected

    Optional, but OpenAI needs every property listed in required.

    Fix: Made it required and nullable: the model sends null when there’s no value.

  • $.order_totalrequiredRejected

    Optional, but OpenAI needs every property listed in required.

    Fix: Made it required and nullable: the model sends null when there’s no value.

  • $.attachments[]additionalPropertiesRejected

    OpenAI needs additionalProperties: false on every object.

    Fix: Set it to false.

  • $.attachments[].urlformatNot supported

    OpenAI 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.

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.

Every change on What’s new

How we make toolsReport a mistake

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.