Skip to main content

Overview

Structured Outputs force the model’s response to strictly follow a JSON Schema you define, ensuring the return value can be parsed directly by your program without regex or post-processing. Unlike asking the model to “please return JSON” in the prompt, Structured Outputs rely on Constrained Decoding: the upstream provider compiles the JSON Schema into grammar rules and constrains generation token-by-token during inference, making it impossible for the model to produce output that violates the schema. Typical use cases:
  • Extracting entities and fields from unstructured text
  • Classification / labeling / sentiment analysis
  • Standardized passing of intermediate results in multi-step reasoning
  • Strongly-typed constraints on Agent tool call parameters

Protocol Parameter Comparison

The parameter names differ across the three protocols, but the underlying mechanism is the same: the model output strictly matches the JSON Schema you provide.
ProtocolParameterSupported Models
OpenAI Chat /v1/chat/completionsresponse_format.type: "json_schema"Claude 4.5+, GPT-4o / GPT-5 series, Gemini series
Anthropic Messages /v1/messagesoutput_config.format.type: "json_schema"Claude 4.5+ (direct / Vertex); Bedrock 4.5—4.6 only
OpenAI Responses /v1/responsestext.format.type: "json_schema"Depends on upstream model capabilities

AWS Bedrock Limitations

Claude 4.7 and above on AWS Bedrock uses the Mantle inference path, which does not currently support output_config.format. The gateway automatically strips the format field for these models and marks the degradation in a response header (see Auto-Degradation Mechanism below). Your request will not fail because of this.

Quick Start

Works with all models that support Structured Outputs, across providers.
from openai import OpenAI

client = OpenAI(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com/v1",
)

response = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[
        {"role": "user", "content": "Extract the following information: John Smith, 28 years old, San Francisco"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "John Smith", "age": 28, "city": "San Francisco"}

Using Other Models (GLM-5.2 Example)

The same OpenAI protocol parameters work with all models that support Structured Outputs — just switch the model.
Python
from openai import OpenAI

client = OpenAI(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com/v1",
)

response = client.chat.completions.create(
    model="glm-5.2",
    messages=[
        {"role": "user", "content": "Extract the following information: John Smith, 28 years old, San Francisco"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "John Smith", "age": 28, "city": "San Francisco"}

Claude Native Protocol

Call directly with the Anthropic SDK using the output_config.format parameter.
import anthropic

client = anthropic.Anthropic(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com",
)

response = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Extract the following information: John Smith, 28 years old, San Francisco"}
    ],
    output_config={
        "format": {
            "type": "json_schema",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.content[0].text)
print(data)

Schema Writing Guidelines

Required Fields

All object types must explicitly declare additionalProperties: false; otherwise some upstream providers will reject the request.
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "score": { "type": "number" }
  },
  "required": ["name", "score"],
  "additionalProperties": false
}

Nested Objects

Nested object types also require additionalProperties: false:
{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string" }
      },
      "required": ["name", "email"],
      "additionalProperties": false
    }
  },
  "required": ["user"],
  "additionalProperties": false
}

Cross-Protocol Schema Differences

FeatureOpenAI ProtocolAnthropic Protocol
name fieldRequiredNot supported (automatically handled by the gateway during cross-protocol calls)
strict fieldOptional, recommended trueNot supported
Numeric constraints (minimum, maximum, etc.)SupportedNot supported (automatically stripped by the gateway; does not affect the request)
String constraints (minLength, maxLength)SupportedNot supported (automatically stripped by the gateway)
When calling Claude models via the OpenAI protocol, the gateway automatically converts the Schema format and strips incompatible keywords — no manual adaptation needed.

Auto-Degradation Mechanism

The gateway enables auto-degradation protection for Structured Outputs on all requests by default. When the model or platform does not support it, the gateway will not return an error. Instead, it automatically strips the Schema constraint and marks the degradation reason in a response header. Your request will still receive a normal model response — the output simply won’t be strictly constrained by the Schema. This means you can safely enable Structured Outputs uniformly on the client side without having to check compatibility for each model:
  • Seamless multi-model switching: When switching models between Claude, GPT, Gemini, and GLM with the same codebase, requests won’t fail even if the target model doesn’t support Structured Outputs
  • Transparent fallback routing: When the primary channel is unavailable and fallback routing redirects to a backup channel, even if the backup channel’s model version doesn’t support Structured Outputs, the request still completes normally
  • Simplified client logic: No need to maintain a list of “which models support Structured Outputs” — the gateway handles it automatically; the client only needs to check the response header to decide whether additional parsing is needed

Response Header

X-Structured-Output-Degraded: <reason>
reasonMeaning
model_unsupportedThe model (or the model on its current platform) does not support Structured Outputs
json_object_unsupported_on_anthropicjson_object mode cannot be converted to the Anthropic format
json_schema_missing_schemajson_schema type was specified but the schema field is missing
schema_keywords_strippedSome constraint keywords in the Schema were stripped (e.g., minimum, maxLength)

Detection Example

Python
import httpx

response = httpx.post(
    "https://aihubmix.com/v1/chat/completions",
    headers={
        "Authorization": "Bearer <AIHUBMIX_API_KEY>",
        "Content-Type": "application/json",
    },
    json={
        "model": "claude-sonnet-5",
        "messages": [{"role": "user", "content": "Extract info: John Smith, 28 years old"}],
        "response_format": {
            "type": "json_schema",
            "json_schema": {
                "name": "person",
                "strict": True,
                "schema": {
                    "type": "object",
                    "properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
                    "required": ["name", "age"],
                    "additionalProperties": False,
                }
            }
        }
    }
)

# Check if degradation occurred (e.g., when the request was routed to an unsupported Bedrock channel)
degraded = response.headers.get("X-Structured-Output-Degraded")
if degraded:
    print(f"Structured Output degraded: {degraded}")
    # The model response is still normal, but the output is not strictly constrained by the Schema
else:
    import json
    data = json.loads(response.json()["choices"][0]["message"]["content"])
    print(data)  # {"name": "John Smith", "age": 28}

Difference from json_object Mode

json_schema (Structured Outputs)json_object
Output guaranteeStrictly matches the specified SchemaOnly guarantees valid JSON
Field controlField names, types, and required status are all constrainedNo constraints
Supported protocolsOpenAI / Anthropic / ResponsesOpenAI-compatible protocols only
Claude supportVia output_config.formatNot supported
json_object mode cannot be converted to the Claude native protocol. If you send response_format: {"type": "json_object"} to Claude via the OpenAI protocol, the response header will mark json_object_unsupported_on_anthropic degradation. Use the json_schema type instead.

FAQ

Claude series (via Anthropic API’s output_config.format):
  • Opus / Sonnet / Haiku 4.5 and above
  • Fable / Mythos 5 and above
  • Bedrock platform: 4.5—4.6 only; Vertex AI matches direct API support
OpenAI series (via response_format):
  • GPT-4o and above, GPT-5 series
Gemini series (via responseSchema):
  • Gemini 2.5 and above
Check each model’s capability tags on the Models page.
Claude 4.7+ on AWS Bedrock uses the new Mantle inference path, which does not currently accept the output_config.format parameter. The gateway handles this automatically: it strips the format field and returns a normal response while marking the degradation header X-Structured-Output-Degraded: model_unsupported. Claude 4.5—4.6 on Bedrock is fully supported.
Yes. When calling Claude models via the OpenAI protocol, the gateway automatically:
  1. Converts response_format to output_config.format
  2. Removes Schema keywords not supported by Anthropic (minimum, maxLength, etc.)
  3. Marks schema_keywords_stripped in the response header if any keywords were stripped
The reverse direction (calling OpenAI models via the Claude protocol) is also automatically converted.
Yes. The format (Structured Outputs) in output_config and the effort (thinking intensity) in reasoning are independent parameters that can be set simultaneously:
{
  "output_config": {
    "format": {
      "type": "json_schema",
      "schema": { ... }
    }
  },
  "reasoning": {
    "effort": "high"
  }
}
Most API aggregation platforms return an error outright when a model does not support Structured Outputs. AIHubMix uses a graceful degradation strategy: it automatically strips incompatible parameters, returns the model response normally, and informs the client of the degradation reason via the X-Structured-Output-Degraded response header. Your application will not break because of this.