Skip to content
Docs

OpenResponses Reasoning with AI Gateway

Reasoning models work through a problem before answering. With the OpenResponses API, set the reasoning object to control how much thinking the model does. AI Gateway translates it to each provider's native reasoning configuration, so the same request shape works across providers.

reasoning.ts
const apiKey = process.env.AI_GATEWAY_API_KEY;
 
const response = await fetch('https://ai-gateway.vercel.sh/v1/responses', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${apiKey}`,
  },
  body: JSON.stringify({
    model: 'openai/gpt-6-astra',
    input: [
      {
        type: 'message',
        role: 'user',
        content: 'A bat and ball cost $1.10. The bat costs $1 more than the ball. How much is the ball?',
      },
    ],
    reasoning: {
      effort: 'high',
    },
  }),
});
 
const result = await response.json();
console.log(result.usage.output_tokens_details.reasoning_tokens);
reasoning.py
import os
 
import requests
 
api_key = os.environ["AI_GATEWAY_API_KEY"]
 
response = requests.post(
    "https://ai-gateway.vercel.sh/v1/responses",
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}",
    },
    json={
        "model": "openai/gpt-6-astra",
        "input": [
            {
                "type": "message",
                "role": "user",
                "content": "A bat and ball cost $1.10. The bat costs $1 more than the ball. How much is the ball?",
            }
        ],
        "reasoning": {
            "effort": "high",
        },
    },
)
 
result = response.json()
print(result["usage"]["output_tokens_details"]["reasoning_tokens"])
reasoning.sh
curl -X POST "https://ai-gateway.vercel.sh/v1/responses" \
  -H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-6-astra",
    "input": [
      {
        "type": "message",
        "role": "user",
        "content": "A bat and ball cost $1.10. The bat costs $1 more than the ball. How much is the ball?"
      }
    ],
    "reasoning": {
      "effort": "high"
    }
  }'

Set reasoning.effort to request relative reasoning depth. The HTTP schema accepts none, minimal, low, medium, high, xhigh, and max. Choose a model-supported value from the effort entry in GET /v1/models. The catalog doesn't provide a structured default.

AI Gateway translates shared effort for the serving provider. Some routes map it to token budgets or a smaller set of native levels. In cross-provider translation, max can map to xhigh; Anthropic adaptive thinking can retain max. See API-format differences and provider-specific options when exact native control matters.

Set reasoning.summary to auto to ask for a readable summary of the model's thinking alongside the answer:

{
  "reasoning": {
    "effort": "low",
    "summary": "auto"
  }
}

When the provider reports reasoning, the output array can contain a reasoning item and usage can report reasoning tokens:

const result = await response.json();
 
const reasoning = result.output.find(
  (item: { type: string }) => item.type === 'reasoning',
);
const message = result.output.find(
  (item: { type: string }) => item.type === 'message',
);
 
console.log(result.usage.output_tokens_details.reasoning_tokens);
for (const block of message.content) {
  if (block.type === 'output_text') console.log(block.text);
}

The raw chain of thought isn't returned. A reasoning item may carry an encrypted_content field rather than readable text, so treat it as an opaque value to pass back rather than something to display. Use summary: "auto" to request readable text on models that support summaries. An empty summary doesn't prove that reasoning was disabled.

Last updated September 8, 2026

Was this helpful?

supported.