Force the model to return well-formed JSON that matches a schema you define.
Structured outputs guarantee the model produces valid JSON that conforms to a schema you supply. Instead of parsing free-form text, your code receives a document it can deserialize directly — no regex, no error handling for malformed output.
There are two ways to request structured output:
response_format: { type: "json_schema", json_schema: { ... } } — strict schema enforcement; the model cannot produce output that violates the schema.response_format: { type: "json_object" } — JSON mode; the model returns valid JSON but without a specific shape enforced.Both require the model to support structured output. Check the capabilities field in GET /api/models/{slug} for json_mode or json_schema support.
response_format with a JSON schema#Pass a JSON Schema object alongside response_format. The schema describes the shape of the object you want back.
{
"model": "openai/gpt-5.4",
"messages": [
{
"role": "user",
"content": "Extract the product name, price in DA, and availability from this listing: 'Clavier mécanique RGB, 4 500 DA, en stock.'"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "product_listing",
"strict": true,
"schema": {
"type": "object",
"properties": {
"product_name": { "type": "string" },
"price_da": { "type": "number" },
"in_stock": { "type": "boolean" }
},
"required": ["product_name", "price_da", "in_stock"],
"additionalProperties": false
}
}
}
}The model's message.content will be a JSON string you can parse directly:
{
"product_name": "Clavier mécanique RGB",
"price_da": 4500,
"in_stock": true
}Not all models support structured outputs. Use the catalog to find compatible models:
curl "https://opendunes.com/api/models?capability=json_mode"Models that support strict schema enforcement will list json_schema under capabilities. Models with json_mode only will produce valid JSON but cannot guarantee schema conformance.
additionalProperties: false at every object level when using strict: true — this closes the schema so the model has no room to add unexpected keys.required when using strict mode. If a field is truly optional, use a union with null rather than omitting it from required.import os, json
from openai import OpenAI
client = OpenAI(
base_url="https://opendunes.com/v1",
api_key=os.environ["OPENDUNES_API_KEY"],
)
resp = client.chat.completions.create(
model="openai/gpt-5.4",
messages=[
{"role": "system", "content": "Extract structured data from the user text."},
{"role": "user", "content": "Laptop Asus Vivobook, 85 000 DA, rupture de stock."},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "product",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"price_da": {"type": "number"},
"in_stock": {"type": "boolean"},
},
"required": ["name", "price_da", "in_stock"],
"additionalProperties": False,
},
},
},
)
product = json.loads(resp.choices[0].message.content)
print(product)Structured outputs are compatible with streaming ("stream": true). The JSON is emitted as token deltas exactly like normal streaming — accumulate the full content string across all chunks, then parse once the stream ends with [DONE].
Do not attempt to parse partial JSON mid-stream; wait for the complete payload.
If the model cannot produce output that satisfies the schema, the request fails with a 400 invalid_request error rather than returning malformed JSON. Common causes:
strict: true is set but additionalProperties is not false at every level.Use "type": "json_object" as a fallback when strict enforcement isn't required.