Skip to navigation

Reasoning

Overview

ASI:One models can reason before they answer. When reasoning is on, the model produces a train of thought first, then writes its actual reply. You get both back: the reasoning in reasoning_content, the answer in content.

Reasoning helps on problems with several steps, ambiguous requirements, or a chain of logic to follow. It costs extra tokens and adds latency, so how much of it you get is worth choosing per request.

asi1 and asi1-ultra always reason, at the deepest depth unless you ask for a lighter one. asi1-mini does not reason unless you turn it on. See Model support.

How you ask for reasoning depends on the endpoint:

  • On /v1/chat/completions, use reasoning_effort for depth, plus the ASI:One parameters enable_thinking, thinking_budget and use_reasoning_history, described below.
  • On /v1/responses, use OpenAI’s standard reasoning object. If you are already writing against the OpenAI Responses API, nothing changes.

Turning reasoning on

Set enable_thinking to true. It is a top-level field, honored on asi1-mini. On asi1 and asi1-ultra the model always thinks, so the flag is accepted but does not switch reasoning off. Control the depth with reasoning_effort instead.

curl -X POST https://api.asi1.ai/v1/chat/completions \
-H "Authorization: Bearer $ASI_ONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "asi1",
"messages": [
{"role": "user", "content": "A train leaves at 14:05 and arrives at 17:40, stopping twice for 12 minutes each. How long is it moving?"}
],
"enable_thinking": true
}'

The OpenAI SDK does not know about enable_thinking, so pass it through extra_body. With raw HTTP it is a normal top-level field.

Reading the reasoning

The reasoning arrives in a reasoning_content field alongside the usual content.

On a normal response it sits on the message:

{
"choices": [
{
"message": {
"role": "assistant",
"reasoning_content": "Total elapsed is 3h35m. Two stops of 12 minutes each is 24 minutes...",
"content": "The train is moving for 3 hours and 11 minutes."
}
}
]
}

When streaming, it arrives in the delta, generally before any content deltas:

data: {"choices":[{"delta":{"reasoning_content":"Total elapsed is 3h35m..."}}]}
data: {"choices":[{"delta":{"content":"The train is moving"}}]}

Treat reasoning_content as display-only and always optional. It is there for transparency and debugging; you should not parse it for structured values, and you should not assume it is present. It is null when reasoning is off, and an empty string when the model reasoned without producing text, which is common at the lowest depths. Handle both.

Choosing a reasoning depth

reasoning_effort is a top-level field that controls how deeply the model thinks. Its values map to three depths:

reasoning_effortWhat you get
lowLight reasoning: fastest and cheapest, for simple tasks
mediumBalanced reasoning: a good fit for everyday work
highDeep reasoning: most thorough, for hard or multi-step problems. The default when the request sets no depth parameter
{
"model": "asi1-ultra",
"messages": [{ "role": "user", "content": "..." }],
"reasoning_effort": "low"
}

Those three are the scale to write against. A client built on OpenAI’s SDK may send minimal or xhigh instead, and those are accepted too rather than failing the request: minimal gives the same depth as low, and xhigh the same as high.

Deep reasoning is not free: high spends substantially more output tokens than medium for a modest gain in quality. The depth a request gets when it sets none of the depth parameters is the deep one, so an unconfigured request is also the most expensive one. Send medium or low explicitly on everyday work, and keep high for hard multi-step problems and code audits.

Notes:

  • On asi1 and asi1-ultra, reasoning_effort is the primary way to control reasoning. Omit both reasoning_effort and thinking_budget and the request runs at the deep depth.
  • On asi1-mini, reasoning_effort has no effect; use enable_thinking there.
  • reasoning_effort takes precedence over thinking_budget when both are sent.

Legacy depth control

thinking_budget is the older way to size reasoning, kept working for clients already using it. It is not a token cap: the value selects one of the same three depths, so only the band matters, not the exact number.

thinking_budgetDepth
4096 or lesslow
up to 12288medium
above 12288high

Omit both depth parameters and the deep default applies. On new code reach for reasoning_effort instead: it is the direct control, and it wins when both are sent.

To stop the model reasoning, set enable_thinking to false on asi1-mini. That is the only model where reasoning can be switched off; on asi1 and asi1-ultra it always runs, and the flag only leaves it at its shallowest.

{
"model": "asi1",
"messages": [{ "role": "user", "content": "..." }],
"thinking_budget": 2048
}

A lower band trims latency and cost but gives the model less room on hard problems. asi1-mini accepts the field but its depth does not change with it. See Model support.

Carrying reasoning across turns

use_reasoning_history decides whether the model sees its own reasoning from earlier turns. Set it to true on asi1 and asi1-ultra and each turn starts with what the model concluded in the last one; leave it unset and prior reasoning is stripped, so the model re-derives those conclusions from scratch.

It is worth turning on for agentic and tool-calling work, where a run depends on conclusions reached several steps earlier. When you do, replay each assistant message’s reasoning_content back verbatim - do not reorder, truncate or edit it, or the model sees a history it did not produce.

asi1-mini accepts the field; whether it changes anything there is not something we have measured.

Reasoning on the Responses API

/v1/responses also takes OpenAI’s standard reasoning object, so a client already written against OpenAI’s API needs no changes to control reasoning here.

{
"model": "asi1",
"input": "A train leaves at 14:05 and arrives at 17:40...",
"reasoning": { "effort": "medium" }
}

effort accepts the same three depths, plus none:

effortWhat you get
noneReasoning off on asi1-mini; shallowest depth otherwise
lowLight reasoning
mediumBalanced reasoning
highDeep reasoning

none turns reasoning off on asi1-mini. asi1 and asi1-ultra always think, so there it leaves the model at its shallowest depth rather than switching reasoning off.

minimal and xhigh are accepted too, so a client built on OpenAI’s SDK works unchanged: minimal gives the same depth as low, and xhigh the same as high. Any value outside OpenAI’s scale is rejected with a 400.

If you omit reasoning entirely, or send it without an effort, the request falls back to enable_thinking and thinking_budget, so both styles work on this endpoint and you can migrate at your own pace.

On this endpoint the reasoning comes back as a reasoning output item rather than a reasoning_content field, with the text in that item’s content. It streams as response.reasoning_text.delta events, followed by response.reasoning_text.done.

The same per-model support applies: on asi1 and asi1-ultra the effort sets the reasoning depth, and on asi1-mini it turns reasoning on or off.

Model support

Not every parameter applies to every model.

Parameterasi1asi1-ultraasi1-mini
enable_thinkingCannot switch reasoning off; false selects the lowest depthCannot switch reasoning off; false selects the lowest depthYes
thinking_budgetSelects a depth tierSelects a depth tierNo effect
reasoning_effortYesYesNo effect
use_reasoning_historyYesYesAccepted; effect unmeasured
reasoning.effort (/v1/responses)YesYesOn or off only

You can send the same request body to any of the three models without branching your code: no parameter ever turns a request into an error. Only the controls differ: use reasoning_effort for depth on asi1 and asi1-ultra, and enable_thinking to switch reasoning on and off on asi1-mini.

Reasoning costs latency and tokens, so it is worth controlling per request. Send your reasoning parameters explicitly wherever the difference matters to you rather than leaving it to a default.

Next steps

  1. Responses API - Where OpenAI’s reasoning object applies, and how reasoning streams there
  2. Chat Completions API - Where enable_thinking applies, and how reasoning streams there
  3. Planner Mode - Break complex requests into steps executed against tools and agents
  4. ASI:One Models - Which model to reach for
  5. Tuning - Where depth sits in the order of things to try