Force models to return valid JSON matching an exact schema.
Structured Outputs let you enforce that a model’s response conforms to a JSON schema you define. Instead of asking the model to try to return JSON, the API guarantees the output matches your schema — no extra parsing, no malformed responses.
Structured Outputs are available on models that support response_format with json_schema (e.g. gpt-4o, gpt-4o-mini). For other models, use json_object mode with a system prompt.
class ProductReview(BaseModel): sentiment: Literal["positive", "neutral", "negative"] score: int # 1-5 key_issues: list[str] recommended: boolresponse = client.beta.chat.completions.parse( model="gpt-4o", messages=[ {"role": "system", "content": "Extract a structured review from the customer feedback."}, {"role": "user", "content": "I love the design but the battery only lasts 4 hours. Not worth the price."} ], response_format=ProductReview,)
class SupportTicket(BaseModel): category: Literal["billing", "technical", "account", "general"] priority: Literal["low", "medium", "high", "urgent"] summary: strresponse = client.beta.chat.completions.parse( model="gpt-4o-mini", messages=[ {"role": "system", "content": "Classify the support ticket."}, {"role": "user", "content": "My card was charged twice for the same subscription last week."} ], response_format=SupportTicket,)
For models that don’t support json_schema, use json_object mode with a system prompt instructing the model to return JSON.
response = client.chat.completions.create( model="gpt-4o-mini", messages=[ { "role": "system", "content": 'Return a JSON object with keys: "name" (string), "score" (number 1-10), "tags" (array of strings).' }, {"role": "user", "content": "Analyze this product description: ..."} ], response_format={"type": "json_object"},)data = json.loads(response.choices[0].message.content)
json_object mode guarantees valid JSON but not schema conformance. Always validate the output against your expected shape before using it in production.