Skip to content

Guides

Structured output

When your code needs to read the answer, ask for JSON. response_format on the OpenAI-compatible API is passed to the model, so you get an object you can parse rather than prose.
OptionYou get
{"type": "json_schema", …}JSON shaped by your schema. The most reliable choice.
{"type": "json_object"}Valid JSON, shaped by your prompt.
A tool callArguments shaped by the tool's schema; works on both APIs.

JSON Schema#

import jsonimport osfrom openai import OpenAIclient = OpenAI(base_url="https://fullsendai.com/v1", api_key=os.environ["FULLSEND_API_KEY"])reply = client.chat.completions.create(    model="deepseek-v4.1-flash",    messages=[{"role": "user", "content": "Extract the bug report: 'Login fails on Safari 18 with a 500 since Tuesday'"}],    response_format={        "type": "json_schema",        "json_schema": {            "name": "bug",            "strict": True,            "schema": {                "type": "object",                "properties": {                    "summary": {"type": "string"},                    "browser": {"type": "string"},                    "status_code": {"type": "integer"},                },                "required": ["summary", "browser", "status_code"],                "additionalProperties": False,            },        },    },)bug = json.loads(reply.choices[0].message.content)
message.content
{"city": "Tokyo", "country": "Japan"}

JSON mode#

"response_format": {"type": "json_object"} asks only for valid JSON. Say in the prompt which keys you want, and include the word “JSON”; some models require it.

Validate in your code#

How strictly a schema is followed depends on the model. Parse and validate before you trust the result, and check finish_reason: an answer cut off at length isn't complete JSON. With the OpenAI SDKs' helpers you get both at once:

from pydantic import BaseModelclass Bug(BaseModel):    summary: str    browser: str    status_code: intreply = client.chat.completions.parse(    model="deepseek-v4.1-flash",    messages=[{"role": "user", "content": "Extract the bug report: ..."}],    response_format=Bug,)bug = reply.choices[0].message.parsed

On the Anthropic API#

The Messages API has no response_format. Define one tool whose input_schema is the shape you want and set tool_choice to {"type": "tool", "name": "…"}; the tool_use block's input is your object. See Tool calling.

Stuck? Email [email protected]System statusChangelog