Core

Structured output

JSON mode and json_schema, and why the list of models that support it is shorter than any supplier's catalogue says.

Pass response_format, in either of OpenAI’s two forms.

reply = client.chat.completions.create(
    model="gpt-oss-120b",
    messages=[{"role": "user", "content": "Nairobi, Kenya. Population about 5.5 million."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "city",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"},
                    "country": {"type": "string"},
                    "population": {"type": "integer"},
                },
                "required": ["city", "country", "population"],
                "additionalProperties": False,
            },
        },
    },
)

import json
print(json.loads(reply.choices[0].message.content))
reply = client.chat.completions.create(
    model="gpt-oss-120b",
    messages=[
        {"role": "system", "content": "Reply with JSON only."},
        {"role": "user", "content": "Nairobi, Kenya. Population about 5.5 million."},
    ],
    response_format={"type": "json_object"},
)

json_object needs the word JSON somewhere in your messages, same as OpenAI. Prefer json_schema where the model supports it: it constrains the shape rather than asking politely.

The supported list is shorter than suppliers claim

Check Can do on Models or supported_parameters on GET /v1/models. Asking a model that does not declare it is a 400:

{
  "error": {
    "message": "Model \"llama-3.3-70b\" does not support `response_format`.",
    "type": "invalid_request_error",
    "param": "response_format",
    "code": "unsupported_parameter"
  }
}

An error before any billable work, rather than a paid-for answer in the wrong shape.

Reasoning models

They think before producing the JSON, and the thinking is billed. Give them room: a max_tokens sized for the JSON alone can be consumed entirely by reasoning, leaving you an empty string. See Models.