Core

Structured output

JSON mode and json_schema on the chat completions endpoint, the models that accept response_format, and the error for a model that does not.

On /v1/chat/completions, send response_format in one of the two OpenAI forms.

import json

reply = client.chat.completions.create(
    model="gemini-3.5-flash",
    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,
            },
        },
    },
)

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

With json_object, put the word JSON in your messages, as with OpenAI. Use json_schema when you can, because it controls the shape of the answer.

Models that accept response_format

Look for structured-output in supported_parameters of GET /v1/models, or for json in the table on Models. At this time, the GPT and Gemini models show it, and the Claude models do not.

If you send response_format to a model that does not show it, you get a 400 error. We do not charge for that request:

{
  "error": {
    "message": "Model \"claude-sonnet-5-5\" does not support `response_format`. See supported_parameters on GET /v1/models for a model that does.",
    "type": "invalid_request_error",
    "param": "response_format",
    "code": "unsupported_parameter"
  }
}

Models that think first

GPT and Gemini models think before they write the JSON, and we charge for the thought tokens. If max_tokens is only large enough for the JSON, the model can use all of it before it writes the answer. Then you get an empty string. See Models.