json

FormatValidateConvert

JSON to OpenAI

JSON
Language
Structured output

Result· read-only

—OpenAI

The result appears here.

Generate

JSON to an OpenAI Structured Outputs schema.

Your document never leaves the browser.

A strict Structured Outputs schema for OpenAI, from an example answer — in your browser.

Structured Outputs makes an OpenAI model answer in exactly the JSON shape you give it. Paste an example of the answer you want and this page writes the schema in the strict dialect OpenAI accepts, so you do not have to learn the rules by trial and error.

null

sent for a key the sample lacked, since all are required

10

levels of nesting, one of three limits checked

0

bytes leave your machine

What strict mode requires

In strict mode, OpenAI wants every property of every object listed as required, and every object closed with additionalProperties: false. So a key your sample lacked in places cannot simply be optional. Here gift-wrap is listed as required and its type becomes ["boolean", "null"]: the model always sends the key, and sends null when it has nothing to say.

The list under the result names each change it made, with its path. For this sample it is one line, saying one optional field was made nullable at $.items[]["gift-wrap"]. The nested objects are written once under $defs and referred to with $ref, which strict mode supports.

1

The sample, an order with two line items, pasted as the source

{
  "order_id": 1042,
  "placed_at": "2026-09-25T10:15:00Z",
  "paid": true,
  "customer": { "name": "Ada Lovelace", "email": "[email protected]" },
  "items": [
    { "sku": "PEN-01", "qty": 2, "price": 3.5, "note": null },
    { "sku": "INK-07", "qty": 1, "price": 12, "note": "Fragile", "gift-wrap": true }
  ]
}
2

The schema written for it

{
  "type": "object",
  "properties": {
    "order_id": {
      "type": "integer"
    },
    "placed_at": {
      "type": "string"
    },
    "paid": {
      "type": "boolean"
    },
    "customer": {
      "$ref": "#/$defs/Customer"
    },
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Item"
      }
    }
  },
  "required": [
    "order_id",
    "placed_at",
    "paid",
    "customer",
    "items"
  ],
  "additionalProperties": false,
  "$defs": {
    "Customer": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string"
        }
      },
      "required": [
        "name",
        "email"
      ],
      "additionalProperties": false
    },
    "Item": {
      "type": "object",
      "properties": {
        "sku": {
          "type": "string"
        },
        "qty": {
          "type": "integer"
        },
        "price": {
          "type": "number"
        },
        "note": {
          "type": [
            "null",
            "string"
          ]
        },
        "gift-wrap": {
          "type": [
            "boolean",
            "null"
          ]
        }
      },
      "required": [
        "sku",
        "qty",
        "price",
        "note",
        "gift-wrap"
      ],
      "additionalProperties": false
    }
  }
}

Schema or request fragment

1

An answer and a score

{ "answer": "yes", "score": 0.9 }
2

With Output Request fragment and API Chat Completions

{
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "root",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "answer": {
            "type": "string"
          },
          "score": {
            "type": "number"
          }
        },
        "required": [
          "answer",
          "score"
        ],
        "additionalProperties": false
      }
    }
  }
}

Option

Output

Output: Schema, the default, writes the bare schema. Request fragment wraps it in the part of the request body that carries it, with strict set to true.

Option

API

API, shown for a fragment: Responses API, the default, which puts the schema under text.format, or Chat Completions, which puts it under response_format. Mistral, Groq, xAI and other OpenAI-compatible APIs take the Chat Completions shape.

Option

Name

Name, shown for a fragment: the schema name the request carries. It defaults to your root name in snake_case.

Other changes and limits

A root that is not an object, such as a list of records, is wrapped as a required property named items, because OpenAI’s root must be an object. A value the inference could not type is sent as a string, and the list says where.

Three of OpenAI’s published limits are checked as you type: 5,000 object properties in one schema, 10 levels of nesting, and 120,000 characters of property and definition names. A warning appears under the schema when any of them is exceeded.

1

A list of records as the root

[
  { "id": 1 },
  { "id": 2 }
]
2

Wrapped as items, and the list under the schema says so

{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/RootItem"
      }
    }
  },
  "required": [
    "items"
  ],
  "additionalProperties": false,
  "$defs": {
    "RootItem": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    }
  }
}
  • OpenAI wrapped the root at $ as the required items object.

Your sample stays here

Inference and code generation both run inside this browser tab. The sample is never uploaded, stored on a server or logged, because the page has no server to send it to, and once loaded it carries on working with the connection off.

Read next:

FAQ

Frequently asked questions

Didn’t find your answer?Write to us on the contact page →
Does this page call OpenAI?

No. It writes the schema in this tab; you send it with your own key from your own code, and neither the sample nor the key ever reaches this site.

Why is every field required?

Strict mode requires it. A field that may be missing is instead allowed to be null, which carries the same meaning.

Can I use the schema without strict mode?

Yes. It is valid JSON Schema, only stricter than it needs to be; for a plain JSON Schema of the sample, use the JSON Schema page.

Keyboard shortcuts

Send feedback

Questions, bug reports and feature requests are all welcome. A bug report is easiest to act on with the shape of the document that caused it — never send anything confidential.

Email us

Contact page, in a new tab, so this page stays as it is.

Settings

Indent

The result is written with it — YAML and XML at 2 spaces when it is Tab.

Code text size
14 px

Both panes.

Wrap long lines

Load from a URL

Your browser fetches it directly — the request goes to that site, never to us.