Guides

Structured output

When your code needs to parse the model's output, you can require it to follow a JSON Schema exactly. No more repeating format rules in the prompt or stripping stray explanations.

OpenAI-compatible format

Use response_format with type json_schema:

structured_openai.py
import json
from openai import OpenAI

client = OpenAI(api_key="sk-...", base_url="https://api.flyrouter.ai/v1")

resp = client.chat.completions.create(
    model="gpt-6.1-sol",
    messages=[{"role": "user", "content": "Extract the contact: Jane Doe, phone 555-0100, works in Seattle."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "contact",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "phone": {"type": "string"},
                    "city": {"type": "string"},
                },
                "required": ["name", "phone", "city"],
                "additionalProperties": False,
            },
        },
    },
)
print(json.loads(resp.choices[0].message.content))

If you only need valid JSON without a fixed set of fields, use "response_format": {"type": "json_object"} and say in the prompt that you want JSON.

Anthropic native format

Claude uses output_config.format:

structured_claude.py
import json
from anthropic import Anthropic

client = Anthropic(api_key="sk-...", base_url="https://api.flyrouter.ai")

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "phone": {"type": "string"},
        "city": {"type": "string"},
    },
    "required": ["name", "phone", "city"],
    "additionalProperties": False,
}

msg = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Extract the contact: Jane Doe, phone 555-0100, works in Seattle."}],
    output_config={"format": {"type": "json_schema", "schema": schema}},
)
print(json.loads(msg.content[0].text))

The older output_format parameter has been replaced by output_config.format. Newer Claude models also no longer accept a prefilled final assistant message to steer the format; use the approach on this page instead.

Writing good schemas

  • List every field in required and add "additionalProperties": false for the most consistent output.
  • Add a description to fields so the model knows what goes in each one.
  • Use enum for fixed values such as category labels.
  • Structured output constrains the format, not the facts. Still validate important fields in your code.
FlyRouter

One key, every top AI model