Skip to main content
For the TypeScript examples, use the TypeScript setup, including "type": "module" and the tsx runner. Use structured output when the next step needs an object rather than conversational text: extracting a contact, classifying a ticket or preparing a typed report. The runtime asks the model to call its StructuredOutput tool and validates the submitted object against JSON Schema.

Extract and validate a contact

Start with the quickstart, set OPENAI_API_KEY, and install Zod:
Save this as extract.ts and run node --env-file=.env --import tsx extract.ts.
Read result.structuredOutput; do not parse result.text as a substitute. The local parse narrows the result and enforces the application’s stronger constraints before using it. JSON Schema validation checks the expressed shape and constraints; it cannot prove extracted facts are true.

Choose a schema

defineOutputFormat accepts either a Zod schema or a JSON Schema object. Zod is converted to JSON Schema; arbitrary application transforms or refinements do not become provider behavior. Prefer explicit object properties and required fields, and validate stronger business rules in your application. Provider support varies. The example uses a plain string for the model-facing email field because schema libraries can emit patterns that a provider handles poorly. The application still requires a valid email before reporting success. A simple portable wire schema does not mean skipping application validation. For JSON Schema without Zod, this is the equivalent format declaration for a small summary:
The generic type describes your intended shape; it is not a separate validator. OutputOf<typeof format> can extract the format’s compile-time output type. Runtime result fields still need narrowing at your application’s boundary.

Allow the submission tool

StructuredOutput is case-sensitive. A schema-only Agent should use allowedTools: ["StructuredOutput"]. To combine structured output with other work, include the intended tools in that same allowlist. disallowedTools: ["*"] blocks the submission tool too. Do not carry a text-only deny-all policy into a structured-output example. An empty allowedTools array is also not a schema-only policy: it adds no allowlist restriction.

Handle retries and failures

maxRetries is a non-negative schema retry count. Invalid or missing schema submissions may cause another model call. Retries also consume assistant turns, provider usage and the enclosing run’s time budget; maxTurns can end the run before schema retries are exhausted. An exhausted schema retry budget produces an unsuccessful error_max_structured_output_retries result. Inspect result.subtype and result.error?.message; do not treat every such failure as an invalid field. A provider can end its stream before completing a tool call. Setup and transport failures may instead reject the promise. If a submission repeatedly fails, check the tool policy, simplify the model-facing schema, confirm model tool support, and inspect the terminal error. Do not keep retrying a schema the provider cannot produce. The standalone extraction project includes the complete installation and execution flow.