Reasoning
Reasoning lets a model spend extra output tokens planning before it answers. Use it for multi-step coding, math, analysis, and tool-use planning, where a better answer is worth a slower, costlier request.
Support is per vendor route: send one control, and Gateway translates it for the serving route and warns you if the level changed.
Request reasoning
On /v1/responses, send one control:
reasoning: {"effort": "high"}names a level:none,minimal,low,medium,high,xhigh, ormax. It works on any route with an effort control, including the newest Claude models.thinking: {"type": "enabled", "budget_tokens": 2048}sets a token budget. Routes that take levels get one derived from it: under 4,096 islow, 4,096 to 16,383medium, and 16,384 or morehigh.
/v1/responses ignores a top-level reasoning_effort; use reasoning.effort, or reasoning_effort on /v1/openai/chat/completions. The surface table lists every spelling.
Reasoning tokens count against max_tokens. A model that spends the whole budget thinking returns a 200 with empty content and a reasoning_exhausted warning, so raise max_tokens or lower the effort.
To turn reasoning off, send thinking: {"type": "disabled"} on a route with disable_supported: true, or reasoning: {"effort": "none"} on a route whose effort_values include none. Claude Fable 5, Fable 5.1, and Opus 5.5 ignore the disable.
How Gateway picks the level
GET /v1/models lists each route’s support under vendors.<vendor>.capabilities.reasoning (route fields), and it can differ by vendor: moonshot/kimi-k3 accepts max on moonshot but tops out at xhigh on baseten, and doesn’t reason at all on fireworks. effort_values is empty on every Claude route, so use the per-vendor table for Claude.
When you name a level, Gateway prefers routes that accept it before comparing price, though a vendor pin, your own vendor keys, or a policy can still pick one that doesn’t. A known level the route doesn’t accept is never rejected: Gateway sends the nearest accepted level (higher only when nothing lower exists) with a reasoning_effort_adjusted warning whose detail.applied_effort is what ran, or null when the route has no effort control. include_routing_metadata: true adds routing.reasoning_effort_applied and routing.vendor_used.
Read reasoning output
On /v1/responses, reasoning arrives as thinking blocks ahead of the text. Keep them apart from the answer; most apps shouldn’t show reasoning to end users.
signature is set on Claude routes and null elsewhere. When Anthropic encrypts reasoning, the block has empty thinking and the payload on redacted_data. usage.reasoning_output_tokens is the part of output_tokens spent reasoning, or null when the vendor doesn’t report it (every Claude route).
Replay reasoning in multi-round tool loops
On Claude routes, the assistant turn you send back in a tool loop must keep its thinking block’s signature.
Gateway drops an unsigned thinking block before sending to a Claude route, since Anthropic rejects it. The request succeeds, but the model loses reasoning you already paid for. A signature is valid only on the vendor that produced it, so failover between anthropic and bedrock also drops signed blocks.
On /v1/responses and /v1/anthropic, echo assistant content blocks back unchanged. On /v1/openai/chat/completions and /v1/ai-sdk/chat/completions, thinking and thinking_signature are Gateway extensions on the message, so carry both:
/v1/openai/responses and LangChain can’t replay reasoning, and the chat completions surfaces can’t carry a redacted block. For long Claude tool loops, use /v1/responses or /v1/anthropic.
Reference
Controls and output by surface
reasoning.summary (auto, concise, or detailed) asks OpenAI reasoning models for a reasoning summary, which they don’t return otherwise.
Streaming
/v1/responses streams cumulative frames, each carrying the whole thinking block so far, so read the latest instead of concatenating. /v1/anthropic streams thinking_delta then signature_delta, matching Anthropic. The chat completions surfaces stream delta.thinking, with delta.thinking_signature and any warnings on the final chunk.
Route fields
Effort levels by vendor
Unlisted routes accept their reasoning.effort_values.