OpenRouter structured outputs use JSON Schema to define the response your application expects. Combine a compatible model with local parsing, schema validation, and business rules.
Reliable JSON starts with a contract
Structured outputs ask a model to return data matching a JSON Schema. This is stronger than saying “reply in JSON,” but it is not a substitute for server-side validation. Your application must still reject invalid or unsafe values.
Checked October 15, 2026: model support changes. Confirm the model advertises structured-output support in the live catalog and review the official guide.
Example: extract a task
{
"model":"openai/gpt-5.2",
"messages":[{"role":"user","content":"Email Maria Friday about the launch budget."}],
"response_format":{
"type":"json_schema",
"json_schema":{
"name":"task",
"strict":true,
"schema":{
"type":"object",
"properties":{
"action":{"type":"string"},
"person":{"type":"string"},
"due_date":{"type":["string","null"]},
"needs_clarification":{"type":"boolean"}
},
"required":["action","person","due_date","needs_clarification"],
"additionalProperties":false
}
}
}
}
A valid illustrative result:
{"action":"Email about the launch budget","person":"Maria","due_date":null,"needs_clarification":true}
The date remains null because “Friday” lacks a reference date. A useful schema preserves uncertainty rather than forcing invented precision.
Send the request
Install requests and jsonschema in your virtual environment. The Python payload below contains the same JSON request shown above.
import os, requests, json
payload = json.loads(r'''
{
"model":"openai/gpt-5.2",
"messages":[{"role":"user","content":"Email Maria Friday about the launch budget."}],
"response_format":{
"type":"json_schema",
"json_schema":{
"name":"task",
"strict":true,
"schema":{
"type":"object",
"properties":{
"action":{"type":"string"},
"person":{"type":"string"},
"due_date":{"type":["string","null"]},
"needs_clarification":{"type":"boolean"}
},
"required":["action","person","due_date","needs_clarification"],
"additionalProperties":false
}
}
}
}
''')
r=requests.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={"Authorization":f"Bearer {os.environ['OPENROUTER_API_KEY']}",
"Content-Type":"application/json"},
json=payload,timeout=(5,45))
r.raise_for_status()
text=r.json()["choices"][0]["message"]["content"]
data=json.loads(text)
Validate on your server
from jsonschema import validate, ValidationError
try:
validate(instance=data, schema=payload["response_format"]["json_schema"]["schema"])
except ValidationError as exc:
raise ValueError(f"Model output failed schema: {exc.message}")
Then apply business rules: allowed actions, date ranges, enum membership, maximum lengths, and authorization. Schema validity only says the data has the requested shape.
Schema design rules
- Use small, explicit objects.
- Mark required fields deliberately.
- Use
additionalProperties:falsewhen supported. - Represent uncertainty with nullable values and a clarification flag.
- Prefer enums for closed choices.
- Constrain strings and arrays where supported.
- Version the schema with your application.
Model support and fallbacks
Every fallback must support the requested response format. Filter the model catalog by capability and test the exact schema. If no compatible endpoint exists, return a controlled error rather than silently dropping strictness.
Repair strategy
Use at most one or two bounded repair attempts. Feed back the validation error without sensitive data and ask for corrected output using the same schema. If it still fails, queue human review. Infinite “fix the JSON” loops waste money and may never resolve a semantic error.
Common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Model returns prose | Unsupported format or wrong field | Check capability and request schema |
| Valid JSON, wrong values | No business validation | Add enums, ranges, and domain checks |
| No eligible endpoint | Strict capability/provider filters | Review model and routing policy |
| Truncated JSON | Output limit too small | Increase bounded token budget or shrink schema |
OpenRouter structured outputs FAQ
Is structured output always valid?
No. It improves reliability when supported, but you still need JSON parsing, schema validation, and business rules.
Can I use it with tools?
Yes, but keep tool arguments and final-answer schema separate and validate both.
Read next
See function calling, capability-aware routing, and the complete guide.
Official references
Documentation reviewed 15 October 2026. Examples illustrate the request pattern; confirm model availability and account settings before use. No uptime or performance benchmark is claimed.
