Skip to main content

Reasoning

Many current models reason before answering. Where the depth is adjustable, it is a parameter: reasoning_effort on Chat Completions, reasoning.effort on Responses, output_config.effort (or a thinking object) on Messages. Where it isn't adjustable, the model still reasons, and you pay for it as output tokens.

Works with

Models whose catalog entry lists reasoning_efforts. The levels vary by model and GET /v1/models is authoritative; the per-model ladder is also on the capability matrix. Models with reasoning_efforts: null (mindshub_air, kimi among them) reason internally on every request and the level isn't tunable.

Request

response = client.chat.completions.create(
model="deepseek",
messages=[{"role": "user", "content": "Prove that √2 is irrational."}],
reasoning_effort="high",
)
print(response.choices[0].message.content)

These samples use deepseek, which takes low, high, and max and draws the prepaid wallet.

Requests never fail over the effort level. A recognized level outside a model's ladder is clamped onto it: below the floor, including none on a model without an off switch, you get the cheapest supported rung (which can cost more than the unsupported level you requested); above the ceiling you get the top rung; between rungs you get the lower one. Clamps are reported in X-MindsHub-Clamped-Params. Only an unrecognized value such as a typo is dropped and reported in X-MindsHub-Dropped-Params, letting the model's default apply. On models with reasoning_efforts: null the drop currently comes with no header.

If you send nothing, the model's default_reasoning_effort applies, which for most reasoning models is not "off". Send the lowest listed level explicitly if you want speed over depth.

Extended thinking on Messages

A thinking object on a Messages request ({"type": "enabled", "budget_tokens": 8000}) is forwarded to the target model where that model accepts it, including its budget_tokens; the current Claude 5 models accept it. thinking and redacted_thinking blocks in your message history are replayed to the model unmodified, so a multi-turn tool workflow on a thinking model keeps working. On the OpenAI-shaped APIs there is no thinking object; use the effort level.

Carrying reasoning across turns on Responses

include: ["reasoning.encrypted_content"] carries a reasoning model's thinking across chained turns (previous_response_id); the other include values are ignored. reasoning.summary asks for a summary on the returned reasoning item.

Response

  • Chat Completions and Responses never return reasoning content; you get the final answer. usage.completion_tokens_details.reasoning_tokens (or output_tokens_details.reasoning_tokens) is a subset of the output count, not an addition to it, broken out by the GPT/Grok families and Gemini models. Elsewhere it reads 0, which means no separately-reported reasoning rather than no reasoning: the Claude family bills thinking as output without separating it.
  • Messages returns thinking blocks, on streamed and non-streamed turns alike, in Anthropic's required order (before the text), with their signature, usually with empty or withheld content. Don't assume the first block is your text.

Streaming

On Messages, thinking blocks stream as content_block_* events before the text and carry a signature so a streaming client can replay them. On the OpenAI-shaped APIs nothing about the stream changes. See Streaming.

Per-model differences

  • Levels differ by model: sonnet supports low through max, deepseek takes low, high and max, gpt-mini adds none. Read the model's own list rather than assuming a family shares one ladder.
  • mindshub_air and kimi reason internally with no adjustable level. Budget max_tokens generously for them (a few hundred tokens of headroom) or the reasoning uses the cap and the visible answer arrives truncated with finish_reason: "length".
  • Gemini sets depth through thinking_level, which the effort parameter carries; it accepts no thinking object.

Errors you can hit

None specific to this feature: an out-of-ladder level is clamped, an unrecognized one dropped, both reported in headers. A turn whose reasoning exhausted max_tokens ends with finish_reason: "length" (stop_reason: "max_tokens" on Messages, status: "incomplete" on Responses). See Errors.