Anthropic Messages Extended Thinking with AI Gateway
Anthropic calls reasoning extended thinking. Configure it with the thinking parameter on a Messages request. Other API surfaces call the same capability reasoning: see Reasoning for the cross-provider reference, or Chat Completions reasoning for the OpenAI-shaped equivalent.
Configure thinking for models that support chain-of-thought reasoning. The thinking parameter allows you to control how reasoning tokens are generated and returned. There are two modes:
- Adaptive thinking: Set
thinking: { type: 'adaptive' }. The model decides when and how much to think. Available on Claude 4.6 and later. Required on Claude Opus 4.7 and later. - Extended thinking with a token budget: Set
thinking: { type: 'enabled', budget_tokens: N }for a fixed token budget. Available on Claude 4.6 and earlier. Deprecated on Claude 4.6. Returns a 400 error on Claude Opus 4.7 and later.
See the Anthropic reasoning reference for native thinking modes and provider-specific exceptions.
The thinking parameter works across supported reasoning models, including models from other providers. AI Gateway maps it to the target provider's native reasoning configuration, so you can set a thinking budget on a request to an OpenAI or Google model too.
Discover each model's controls through GET /v1/models. To set effort on adaptive models, send output_config.effort alongside thinking: { type: 'adaptive' }. The Messages request schema accepts low, medium, high, xhigh, and max; choose a level the model supports. The catalog doesn't provide a structured default.
On Claude Opus 4.7 and later, set display: 'summarized' to receive thinking text, which is omitted by default:
import Anthropic from '@anthropic-ai/sdk';
const apiKey = process.env.AI_GATEWAY_API_KEY || process.env.VERCEL_OIDC_TOKEN;
const anthropic = new Anthropic({
apiKey,
baseURL: 'https://ai-gateway.vercel.sh',
});
const message = await anthropic.messages.create({
model: 'anthropic/claude-opus-5',
max_tokens: 2048,
thinking: {
type: 'adaptive',
display: 'summarized',
},
messages: [
{
role: 'user',
content: 'Explain quantum entanglement in simple terms.',
},
],
});
for (const block of message.content) {
if (block.type === 'thinking') {
console.log('🧠 Thinking:', block.thinking);
} else if (block.type === 'text') {
console.log('💬 Response:', block.text);
}
}import os
import anthropic
api_key = os.getenv('AI_GATEWAY_API_KEY') or os.getenv('VERCEL_OIDC_TOKEN')
client = anthropic.Anthropic(
api_key=api_key,
base_url='https://ai-gateway.vercel.sh'
)
message = client.messages.create(
model='anthropic/claude-opus-5',
max_tokens=2048,
thinking={
'type': 'adaptive',
'display': 'summarized',
},
messages=[
{
'role': 'user',
'content': 'Explain quantum entanglement in simple terms.'
}
],
)
for block in message.content:
if block.type == 'thinking':
print('🧠 Thinking:', block.thinking)
elif block.type == 'text':
print('💬 Response:', block.text)curl -X POST "https://ai-gateway.vercel.sh/v1/messages" \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-opus-5",
"max_tokens": 2048,
"thinking": {
"type": "adaptive",
"display": "summarized"
},
"messages": [
{
"role": "user",
"content": "Explain quantum entanglement in simple terms."
}
]
}'For pre-4.7 models, use type: 'enabled' with a budget_tokens value:
import Anthropic from '@anthropic-ai/sdk';
const apiKey = process.env.AI_GATEWAY_API_KEY || process.env.VERCEL_OIDC_TOKEN;
const anthropic = new Anthropic({
apiKey,
baseURL: 'https://ai-gateway.vercel.sh',
});
const message = await anthropic.messages.create({
model: 'anthropic/claude-sonnet-4.5',
max_tokens: 8192,
thinking: {
type: 'enabled',
budget_tokens: 5000,
},
messages: [
{
role: 'user',
content: 'Explain quantum entanglement in simple terms.',
},
],
});
for (const block of message.content) {
if (block.type === 'thinking') {
console.log('🧠 Thinking:', block.thinking);
} else if (block.type === 'text') {
console.log('💬 Response:', block.text);
}
}import os
import anthropic
api_key = os.getenv('AI_GATEWAY_API_KEY') or os.getenv('VERCEL_OIDC_TOKEN')
client = anthropic.Anthropic(
api_key=api_key,
base_url='https://ai-gateway.vercel.sh'
)
message = client.messages.create(
model='anthropic/claude-sonnet-4.5',
max_tokens=8192,
thinking={
'type': 'enabled',
'budget_tokens': 5000,
},
messages=[
{
'role': 'user',
'content': 'Explain quantum entanglement in simple terms.'
}
],
)
for block in message.content:
if block.type == 'thinking':
print('🧠 Thinking:', block.thinking)
elif block.type == 'text':
print('💬 Response:', block.text)curl -X POST "https://ai-gateway.vercel.sh/v1/messages" \
-H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4.5",
"max_tokens": 8192,
"thinking": {
"type": "enabled",
"budget_tokens": 5000
},
"messages": [
{
"role": "user",
"content": "Explain quantum entanglement in simple terms."
}
]
}'Set effort in the separate output_config.effort field, not inside thinking. The following fields belong to thinking:
type: Set to'adaptive'(Claude 4.6 and later) or'enabled'(Claude 4.6 and earlier)budget_tokens: Maximum number of tokens to allocate for thinking. Only valid withtype: 'enabled'display: Withtype: 'adaptive', set to'summarized'to include thinking text in the response. On Claude Opus 4.7 and later, thinking text is omitted by default
When the provider returns thinking content, the response includes thinking blocks. Display settings and model behavior determine whether those blocks contain text:
{
"id": "msg_123",
"type": "message",
"role": "assistant",
"content": [
{
"type": "thinking",
"thinking": "Let me think about how to explain quantum entanglement...",
"signature": "anthropic-signature-xyz"
},
{
"type": "text",
"text": "Quantum entanglement is like having two magic coins..."
}
],
"model": "anthropic/claude-opus-5",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 15,
"output_tokens": 150
}
}Was this helpful?