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.
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" }
}'from openai import OpenAI
client = OpenAI(base_url="https://api.hinow.ai/v1", api_key="HINOW_API_KEY")
resposta = client.chat.completions.create(
model="hinow/himax",
messages=[{"role": "user", "content": "Quanto é 17 x 23? Responda só o número."}],
extra_body={"reasoning": {"effort": "medium"}},
)
mensagem = resposta.choices[0].message
print(mensagem.content) # a resposta
print(getattr(mensagem, "reasoning", None)) # o raciocínio, quando o modelo devolveimport OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.hinow.ai/v1", apiKey: process.env.HINOW_API_KEY });
const resposta = await client.chat.completions.create({
model: "hinow/himax",
messages: [{ role: "user", content: "Quanto é 17 x 23? Responda só o número." }],
reasoning: { effort: "medium" },
} as any);
const mensagem = resposta.choices[0].message as any;
console.log(mensagem.content); // a resposta
console.log(mensagem.reasoning); // o raciocínio, quando o modelo devolveWith 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 reasoning object has four fields, all optional:
effortstringHow much the model can think: `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. Specifying a level enables reasoning; `none` disables it.
enabledbooleanEnables (`true`) or disables (`false`) without choosing a level. Enabled without a level uses the model's default.
excludebooleanWith `true`, the model thinks, but the reasoning does not come back in the response: only the `content`.
max_tokensintegerToken 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:
| Field | Equivalent to | When to use |
|---|---|---|
reasoning_effort: "low" | reasoning: { effort: "low" } | Code written for the OpenAI SDK, which exposes this field natively |
include_reasoning: false | reasoning: { 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.
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.
| Level | For what |
|---|---|
minimal and low | Objective questions, classification, extraction. Little extra cost and fast response |
medium | The default for everyday use: code, text analysis, decisions with some constraints |
high | Multi-step problems, architecture review, math, agent planning |
xhigh and max | The 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.
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 }
}
}| Field | What it says |
|---|---|
message.reasoning | The 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_content | Copy of reasoning, kept for clients already reading this name |
native_finish_reason | The stop reason as the model reported it, before normalization into finish_reason |
usage.completion_tokens_details.reasoning_tokens | How many output tokens were reasoning. When the model does not report, the API estimates from the text |
usage.prompt_tokens_details.cached_tokens | Input 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.
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 respostaTokens 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.
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);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.
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.
- OpenAI SDK:
reasoning_effortworks as in the original; thereasoningobject enters viaextra_body. - Clients in the OpenRouter standard (opencode, agents and compatible SDKs): the
reasoningobject and response fields are the same, without adaptation. - Earlier HINOW clients:
thinking: "on"and"off"still work, andreasoning_contentremains in the response. To choose the level, migrate toreasoning.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.

