Structured Output
Structured Output lets you force the model to return responses in an exact JSON schema. This is useful for processing pipelines, data extraction, or API integrations.
Supported models
Section titled “Supported models”Loading model list …
JSON mode
Section titled “JSON mode”The simplest approach: the model is guaranteed to return valid JSON, but without a fixed schema.
from openai import OpenAI
client = OpenAI( base_url="https://maki.uni-mannheim.de/v1", api_key="your-api-key",)
response = client.chat.completions.create( model="gemma4-26b", messages=[ { "role": "user", "content": "List three German universities with their founding year as JSON.", } ], response_format={"type": "json_object"},)
print(response.choices[0].message.content)# {"universities": [{"name": "Heidelberg University", "founded": 1386}, ...]}JSON schema (Structured Output)
Section titled “JSON schema (Structured Output)”For full control: you define a JSON schema, and the model strictly follows it.
from openai import OpenAIfrom pydantic import BaseModel
client = OpenAI( base_url="https://maki.uni-mannheim.de/v1", api_key="your-api-key",)
class University(BaseModel): name: str city: str founded: int
class UniversityList(BaseModel): universities: list[University]
response = client.beta.chat.completions.parse( model="gemma4-26b", messages=[ { "role": "user", "content": "List three German universities.", } ], response_format=UniversityList,)
result = response.choices[0].message.parsedfor uni in result.universities: print(f"{uni.name} ({uni.city}), founded {uni.founded}")Without Pydantic
Section titled “Without Pydantic”You can also pass the schema directly as a dictionary:
response = client.chat.completions.create( model="gemma4-26b", messages=[ { "role": "user", "content": "List three German universities.", } ], response_format={ "type": "json_schema", "json_schema": { "name": "university_list", "schema": { "type": "object", "properties": { "universities": { "type": "array", "items": { "type": "object", "properties": { "name": {"type": "string"}, "city": {"type": "string"}, "founded": {"type": "integer"}, }, "required": ["name", "city", "founded"], }, } }, "required": ["universities"], }, }, },)- Prefer Pydantic:
client.beta.chat.completions.parse()with Pydantic models is the easiest and safest approach. - Prompting helps: Even with schema enforcement, the model produces better results when the prompt describes the desired structure.
- Large schemas: Complex nested schemas work but may increase response time.