Skip to content

Reasoning (thinking)

Ask the model to think before responding, choose the effort level, receive the reasoning along with the response, and discover which models support this control.

Updated on Sep 16, 2026

Reasoning models think before answering: they generate an internal draft, the reasoning, and only then the final answer. This improves multi-step tasks, math, code, and decisions with many constraints, at the cost of more tokens and more time.

In the API, control is the same for all models, regardless of the technology behind them: you request reasoning with the reasoning object, choose the effort level, decide whether you want to see the trace, and receive everything in the same format. HINOW text models (hinow/himax, hinow/hinova, hinow/hicode, hinow/higenesis and others) accept the control, and the complete list comes from GET /v1/models, in the supported_parameters field.

Enable reasoning

Just add the reasoning object to the call. The effort says how much the model can think; medium is a good starting point.

curl https://api.hinow.ai/v1/chat/completions \
  -H "Authorization: Bearer $HINOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hinow/himax",
    "messages": [{ "role": "user", "content": "Quanto é 17 x 23? Responda só o número." }],
    "reasoning": { "effort": "medium" }
  }'

With the OpenAI SDK, the reasoning object goes into extra_body (Python) or directly in the body (JavaScript, with relaxed typing): the SDK just passes the JSON, and the API understands it.

The fields

The reasoning object has four fields, all optional:

effortstring

How much the model can think: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Specifying a level enables reasoning; `none` disables it.

enabledboolean

Enables (`true`) or disables (`false`) without choosing a level. Enabled without a level uses the model's default.

excludeboolean

With `true`, the model thinks, but the reasoning does not come back in the response: only the `content`.

max_tokensinteger

Token budget for reasoning, in models that work with a budget instead of a level. Specifying a budget also enables reasoning.

There are two shortcuts, for those already using another dialect:

FieldEquivalent toWhen to use
reasoning_effort: "low"reasoning: { effort: "low" }Code written for the OpenAI SDK, which exposes this field natively
include_reasoning: falsereasoning: { exclude: true }Legacy integrations in the OpenRouter standard
thinking: "on" or "off"reasoning: { enabled: true } or { enabled: false }HINOW clients before this version; still accepted

If more than one comes in the same call, explicit thinking wins; then the reasoning object; last reasoning_effort.

Effort levels

The vocabulary is unique across the entire API. Each model applies the scale it has: some work with three steps, others with token budgets, and the API translates the requested level to each one's native control.

LevelFor what
minimal and lowObjective questions, classification, extraction. Little extra cost and fast response
mediumThe default for everyday use: code, text analysis, decisions with some constraints
highMulti-step problems, architecture review, math, agent planning
xhigh and maxThe maximum the model offers. Reserve for cases where quality justifies the time

In HINOW models

HINOW models work with three levels: low, medium, and high. minimal is treated as low, and xhigh and max as the highest level. Enabling reasoning without choosing a level is equivalent to low.

What comes back

The response is the usual chat.completion, with reasoning alongside the content. The call above returned:

{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "hinow/himax",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "391",
        "reasoning": "17×23=391",
        "reasoning_details": [
          { "type": "reasoning.text", "text": "17×23=391", "format": "unknown", "index": 0 }
        ]
      },
      "finish_reason": "stop",
      "native_finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 137,
    "completion_tokens": 10,
    "total_tokens": 147,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 6 }
  }
}
FieldWhat it says
message.reasoningThe reasoning as text. Absent when the model does not return a trace or when you requested exclude
message.reasoning_details[]The structured form: type (reasoning.text, reasoning.summary or reasoning.encrypted), text, format and index. Models that sign the reasoning include signature
message.reasoning_contentCopy of reasoning, kept for clients already reading this name
native_finish_reasonThe stop reason as the model reported it, before normalization into finish_reason
usage.completion_tokens_details.reasoning_tokensHow many output tokens were reasoning. When the model does not report, the API estimates from the text
usage.prompt_tokens_details.cached_tokensInput tokens served from the model cache, when available

To reuse the reasoning in a next call, as some agents do, return the assistant message with reasoning_details intact in the history. If you don't need it, send only content.

Streaming

With stream: true, reasoning arrives first, in delta.reasoning (and delta.reasoning_details), and only then delta.content begins. This is what lets you show "thinking…" to the user before the response.

data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","reasoning":"17","reasoning_details":[{"type":"reasoning.text","text":"17","format":"unknown","index":0}]},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"reasoning":"×23=391"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"391"},"finish_reason":null}]}

data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":137,"completion_tokens":11,"total_tokens":148,"completion_tokens_details":{"reasoning_tokens":7}}}

data: [DONE]
stream = client.chat.completions.create(
    model="hinow/himax",
    messages=[{"role": "user", "content": "Quanto é 17 x 23? Responda só o número."}],
    extra_body={"reasoning": {"effort": "low"}},
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta if chunk.choices else None
    if delta is None:
        continue
    pensamento = getattr(delta, "reasoning", None)
    if pensamento:
        print(pensamento, end="", flush=True)      # o raciocínio chega primeiro
    if delta.content:
        print(delta.content, end="", flush=True)   # depois, a resposta

Tokens at the end

usage comes only in the last event, with reasoning_tokens included. Those who close the connection upon seeing the response miss the count.

Hide the reasoning

In products where the user should not see the draft, request exclude: true. The model thinks the same way and the response comes without reasoning and without reasoning_details, in streaming or not.

const resposta = await client.chat.completions.create({
  model: "hinow/hinova",
  messages: [{ role: "user", content: "Resuma o texto a seguir em três frases: ..." }],
  reasoning: { effort: "high", exclude: true },  // pensa bastante, devolve só a resposta
} as any);

Turn off

For a simple question, reasoning only adds latency. Turn it off with enabled: false (or effort: "none"):

curl https://api.hinow.ai/v1/chat/completions \
  -H "Authorization: Bearer $HINOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hinow/higenesis",
    "messages": [{ "role": "user", "content": "Bom dia! Que dia é hoje?" }],
    "reasoning": { "enabled": false }
  }'

Some models reason always and have no way to turn it off; on them the request is ignored and the response comes with the reasoning anyway. Use exclude: true if you don't want to see it.

Find out which models support it

There is no fixed list: the catalog tells you. In GET /v1/models, each chat model brings supported_parameters, and those that accept the control list reasoning, reasoning_effort and include_reasoning. The same item brings context_length, the size of the context window.

modelos = client.models.list()

com_raciocinio = [
    m.id for m in modelos.data
    if "reasoning" in (getattr(m, "supported_parameters", None) or [])
]
print(com_raciocinio)

Sending reasoning to a model that does not support it does not error: the field is ignored and the call proceeds normally.

Compatibility

  • OpenAI SDK: reasoning_effort works as in the original; the reasoning object enters via extra_body.
  • Clients in the OpenRouter standard (opencode, agents and compatible SDKs): the reasoning object and response fields are the same, without adaptation.
  • Earlier HINOW clients: thinking: "on" and "off" still work, and reasoning_content remains in the response. To choose the level, migrate to reasoning.effort.

In chat and HiNow Code

This is the same control that appears as reasoning level (low, medium, high) in chat.hinow.ai and in the terminal with HiNow Code.

Next steps