# AI structured outputs: what are they?

By Amanda, cofounder of [Wistkey](https://wistkey.com) · 9 Nov 2026 · AI

Canonical: https://styamanda.ai/blog/ai-structured-outputs-explained/

Players keep asking the oracle for a tidy inventory list, then acting surprised when it returns a poem, three bullet points and a field called “miscellaneous_vibes”. The oracle is not broken. Nobody gave it a data sheet. Structured outputs are how we draw the boxes before asking the model to fill them.

## What are AI structured outputs?

**AI structured outputs make a model return data that follows a schema you define.** Instead of hoping a prompt produces the same shape every time, you specify the allowed fields, types and relationships—such as an object with a customer name, an array of line items and a fixed status value. The API constrains the response to that structure so your software can parse it predictably.

The common language for that contract is [JSON Schema](https://json-schema.org/overview/what-is-jsonschema), a declarative way to describe the structure and constraints of JSON data. In plain terms, it lets you say “this field is a string, that one is an integer, these three fields are required, and no surprise keys are allowed”.

That is different from merely asking for JSON in a prompt. A model can produce valid JSON that is still useless to your application: the syntax parses, but a required field is missing, a number arrives as text, or the model renames *due_date* to *deadline*. OpenAI’s [structured outputs guide](https://developers.openai.com/api/docs/guides/structured-outputs) draws the same line: JSON mode guarantees valid JSON, while structured outputs add adherence to the supported schema.

> A schema can make the shape reliable. It cannot make the answer true.

## When should you use structured outputs?

Use them when the model’s answer is going straight into code rather than being read only by a person. Good fits include:

- **Extracting data:** turn an email, receipt or support ticket into named fields.
- **Classification:** choose one category from a controlled list and include a confidence or reason field.
- **Building interfaces:** return sections, steps or cards that a frontend renders in fixed places.
- **Passing work between agents:** give the next system a known input shape instead of making it interpret prose.
- **Generating reports:** produce the same headings, metrics and action arrays on every run.

Google’s [Gemini documentation](https://ai.google.dev/gemini-api/docs/structured-output) gives similar examples—data extraction, structured classification and agentic workflows—and recommends clear field descriptions and strong types. This is the real advantage: less glue code devoted to guessing what the model meant.

Do not force every answer into a schema. If the user wants an explanation, a story or an open-ended conversation, ordinary text is often the better interface. Structure is valuable when something downstream needs a contract. Otherwise it can turn a useful answer into a form with nowhere to put the interesting part.

## Structured outputs vs function calling

The two features are related, but they solve different jobs. A structured response controls the *shape of the model’s final answer*. Function calling controls the *shape of a request for your application to do something*.

If you want a model to read feedback and return a category, severity and summary, use a structured response. If you want it to open a ticket, query a database or send a calendar request, use a function or tool call. The model proposes the arguments; your code validates them, decides whether the action is allowed and performs it. I wrote the longer version of that boundary in [AI function calling: how do tools work?](https://styamanda.ai/blog/ai-function-calling-explained/).

You can also use both. A workflow might call a search tool, inspect the results, then return a structured report for the interface. OpenAI’s current guidance makes the same distinction: use function calling to connect the model to your system; use a structured response format when the user-facing answer needs a schema.

## What structured outputs do not guarantee

Schema compliance removes one class of failure. It does not remove model error. A perfectly valid object can contain the wrong customer, a made-up date or a confident classification based on weak evidence. Treat the schema as a guardrail around representation, not a certificate of truth.

There are several other edges to plan for:

- **Provider subsets differ.** OpenAI, Anthropic and Google each support a subset of JSON Schema, and the accepted keywords are not identical. A schema that works with one API may need changes for another.
- **Refusals and truncation still exist.** A safety refusal or response cut off by a token limit may not match your expected object. Check the API’s completion and refusal signals before parsing.
- **Complex schemas have a cost.** Providers compile schemas into constraints, which can add latency on the first request. Deep, sprawling schemas are also harder for humans to review and models to fill well.
- **Valid values can still be absurd.** A field typed as an integer will accept 900 years as an age unless your application rejects it.

Anthropic’s [structured outputs documentation](https://platform.claude.com/docs/en/build-with-claude/structured-outputs), for example, documents unsupported constraints, schema-complexity limits and exceptional outputs such as refusals. It explicitly recommends validating responses against the original schema when transformations remove unsupported constraints. That is good practice everywhere, not just with one provider.

## How to design a schema that survives production

Start smaller than your instinct tells you. Every field is another decision the model must make and another promise your application must support.

- **Name fields plainly.** Prefer *invoice_date* to *temporal_reference*. The schema is also part of the instruction.
- **Describe meaning, not just type.** “Date the invoice was issued, in YYYY-MM-DD form” is more useful than “string”.
- **Use enums for real closed sets.** Status values such as new, reviewing and resolved are good candidates. Do not use an enum when the world can produce legitimate answers outside your list.
- **Represent uncertainty.** Allow a null value, an unknown category or a confidence field where the source may not contain the answer. Otherwise the model is encouraged to fill every box.
- **Reject surprise properties.** Where the provider supports it, disallow extra fields so a creative new key does not silently enter your pipeline.
- **Keep business rules in code.** Validate ranges, permissions, identifiers and cross-field logic after parsing. A schema is not your authorization layer.

Then test with the ugly inputs: empty documents, conflicting dates, multiple languages, malicious instructions inside source text, very long passages and cases where the correct value is unknown. The same discipline behind [evaluating AI systems](https://styamanda.ai/blog/ai-evaluation-explained/) applies here—measure the task you actually have, including failure handling, rather than celebrating five clean demos.

## A practical release checklist

Before connecting a structured response to a real workflow, I would check five things:

- The chosen model and API support every schema feature you use.
- Your code handles refusal, truncation, timeout and parse failure explicitly.
- The parsed object is validated again against domain rules.
- Low-confidence or high-impact cases go to a person rather than straight into an action.
- Your eval set contains messy, adversarial and missing-information examples.

At [Wistkey](https://wistkey.com), this is the daylight-layer rule I keep returning to: machine-readable does not mean decision-ready. Structured outputs are excellent plumbing. They turn “please answer consistently” from a hopeful prompt into an enforceable interface. But the inventory still needs checking before a player equips it.
