Skip to main content
Structured output constrains a model’s response to match a schema you define. Write the schema in JSON or generate it from a Pydantic model in Python, then pass it in the response_format field of a chat completions request. When you build an application or agent, your code often needs to act on the model’s response. Structured output lets you process the response using a predefined structure instead of parsing free-form text.

Get a structured response

The following sections show how to define a schema with Pydantic or JSON using an example that triages customer support requests. The schema extracts the order ID, issue, and requested follow-up action from each message. The request returns corresponding structured output.

Pass a Pydantic model

Define a Pydantic model for the response and pass it to client.chat.completions.parse() in the OpenAI Python SDK. The SDK converts the model to a JSON schema, sends it in response_format, and parses the response into an instance of your Pydantic model.
Python
This prints output similar to the following:
If the response appears truncated and the finish_reason is length, the model reached the token limit before it finished the JSON, so the content is incomplete. Increase max_tokens and send the request again.

Pass a JSON schema

Pass the schema as JSON. Set type to json_schema and include the schema in json_schema.schema.

Act on the result

Use the parsed response in your application logic. For example, the following code checks ticket.requested_action to determine whether to create a replacement order, issue a refund, or hand off the request to a human:
Python
The application can use the parsed fields to select the appropriate next step.
Validate values before acting on them. The schema constrains the response’s structure and allowed values, but it doesn’t verify business rules. For example, check that an order ID exists before issuing a refund or creating a replacement order.

Example schemas

These examples show different schemas for structured output in application or agent workflows. The Python examples define each schema as a Pydantic model that you pass to client.chat.completions.parse(). The TypeScript and cURL examples pass a JSON schema directly in response_format.
The examples set temperature to 0 to reduce variation in the model’s responses, which is useful for extraction and classification tasks.

Route a request

Have the model choose the next step from a fixed set of options. Your code then sends the request to the matching handler:

Extract records

Extract structured records from unstructured text, such as line items from an email, before you write them to a database:

Evaluate content

Use the model to evaluate input or output against your rules, such as a moderation step before you show content to users:
A nullable field lets the model return null (None in Python) when no category applies. Use this pattern when a field may not have a meaningful value for every input.

Build a form UI

Use structured output to generate a form definition for information your application still needs, such as travel dates for a booking agent. Your application can use the returned definition to render the form with its own UI components.
The input_type enum restricts the model to input types supported by your UI. The pattern constrains each name to the specified format. For select fields, the model populates options with the available choices.

How the engine enforces your schema

A model generates its response one token at a time. At each step, it scores every token in its vocabulary, and the inference engine selects the next token from those scores. When you send a schema with your request, the inference engine compiles it into a grammar that defines which JSON responses are valid. The engine uses this grammar to determine which tokens to allow at each step, based on the response generated so far. The engine allows the response to end when the generated JSON satisfies the grammar. This process is called constrained decoding.

Next steps

To learn more about what you can do with the chat completions API: