Structured output

Ship features that need reliable JSON — extracted fields, labels, configs — without adding recovery logic. With Meta Model API you define the JSON Schema in response_format, and the model constrains decoding to match it exactly.

Understand how it works

Set response_format to type: "json_schema" and provide your schema in the json_schema field. The model constrains token generation to produce only valid JSON matching your schema. This is not post-processing: decoding itself is constrained, so the output is guaranteed to conform.

Recursive schemas aren't supported

Recursive schemas (schemas that reference themselves, such as tree or linked-list structures) are not supported. A request containing a recursive JSON schema returns HTTP 400. Flatten recursive structures into a fixed-depth representation instead.

text.format vs response_format

text.format is the Responses API parameter for structured output. response_format is the Chat Completions equivalent for structured output. A parameter from the other endpoint does not configure structured output, even when accepted for compatibility.

Benefits:

  • Consistent format: Output always follows your defined structure, so you can drop brittle parsing logic.
  • Reduced errors: No unexpected variations in response shape.
  • Simpler integration: Feed model output directly to APIs, databases, or downstream services that expect structured data.

Choose the right use cases

Structured output fits tasks where shape matters:

  • Extracting information: Pull names, dates, locations, or product details from unstructured text.
  • Classifying data: Categorize input into predefined labels or categories.
  • Generating function arguments: Produce structured arguments for downstream functions or APIs from natural language.
  • Generating configurations: Create JSON configuration files from user requirements.

Using a JSON schema

Define your schema directly in response_format. The schema follows standard JSON Schema syntax.

The example below extracts an address into a structured object.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.chat.completions.create(
model="muse-spark-1.3",
messages=[
{
"role": "system",
"content": "Extract the address from the user input into the specified JSON format.",
},
{
"role": "user",
"content": "Please format this address: 1 Hacker Wy Menlo Park CA 94025",
},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "Address",
"schema": {
"type": "object",
"properties": {
"street": {
"type": "string",
},
"city": {
"type": "string",
},
"state": {
"type": "string",
"description": "2-letter state abbreviation",
},
"zip": {
"type": "string",
"description": "5-digit zip code",
},
},
"required": [
"street",
"city",
"state",
"zip",
],
},
},
},
)
print(response.model_dump_json(indent=2))

For all supported fields, see the Chat Completions API reference. The response contains a JSON string in choices[0].message.content:

json
{
"street": "1 Hacker Way",
"city": "Menlo Park",
"state": "CA",
"zip": "94025"
}

Parse that string with json.loads() to work with it as a Python dict.

Using Pydantic models

If you use the OpenAI SDK, call beta.chat.completions.parse() with a Pydantic model as response_format and get a typed result back.

Python (OpenAI SDK)
import os
from openai import OpenAI
from pydantic import BaseModel
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
class Address(BaseModel):
street: str
city: str
state: str
zip: str
response = client.beta.chat.completions.parse(
model="muse-spark-1.3",
messages=[
{
"role": "system",
"content": "Extract the address from the user input.",
},
{
"role": "user",
"content": "Please format this address: 1 Hacker Wy Menlo Park CA 94025",
},
],
response_format=Address,
)
address = response.choices[0].message.parsed
print(address.street) # "1 Hacker Way"
print(address.state) # "CA"

The .parsed attribute returns an Address instance with typed fields.

Stay within schema constraints

Model API validates schemas before decoding starts. A schema that exceeds these limits returns HTTP 400:

ConstraintLimit
Nesting depth10 levels
Total properties5,000, across the whole schema
Total string length120,000 characters (property names, definition names, enum values, and const values combined)
Enum values1,000 by default (raisable per app), across all enum properties
Large string enumsA single string enum with more than 250 values is additionally capped at 15,000 combined characters
Expanded sizeA schema that expands beyond 200,000 nodes once $refs are inlined is rejected

These limits apply to structured-output schemas (response_format / text.format) and to function-tool parameters schemas, on both /v1/chat/completions and /v1/responses. Recursive ($ref-cycle) schemas are also rejected; see the note under How it works.

Enforce strict mode

The strict flag controls whether your schema must conform to the supported strict subset below. strict defaults to false on every surface. When omitted, the schema is accepted as-is (subject to the constraints above) and the strict-subset rules are not enforced. Set strict: true to require that the server validates your schema against the strict subset.

Structured output is always schema-constrained

For structured output (response_format / text.format), the response is always constrained to your JSON Schema, so strict: false currently behaves the same as strict: true — output still conforms to the schema. The strict flag only controls whether the server additionally validates your schema against the strict subset below.

SurfaceParameterstrict default
Chat Completions structured outputresponse_format.json_schema.strictfalse
Responses structured outputtext.format.strictfalse
Chat Completions function tooltools[].function.strictfalse
Responses function tooltools[].strictfalse

When strict: true, your schema must satisfy the strict subset (modeled on OpenAI's):

  • Root must be a plain object: no top-level anyOf, oneOf, allOf, enum, or not.
  • allOf and oneOf: not supported anywhere in the schema; anyOf is supported below the root.
  • additionalProperties: every object must set additionalProperties: false.
  • required: an object's required array must list every key in its properties.

A schema that violates the subset returns HTTP 400 only when strict: true; the same schema with strict omitted (or false) is accepted and normalized. The subset is validated inside $defs / definitions as well.

Combine with other features

Structured output works with the rest of Model API:

  • Tool calling: Define consistent formats for tool arguments or structure data returned from tools before the model processes it.
  • Image understanding: Extract structured data from images, such as detected objects, labels, or recognized text.
  • Chat completion: Use validated structured output from one turn as reliable context in later turns.

Next steps