Esta página ainda não foi traduzida para Português. Exibindo o original em inglês.

Reasoning tokens

How thinking tokens are counted and billed

Some models generate internal "thinking" tokens before producing their visible answer. When a model does this, those tokens are called reasoning tokens, and the API surfaces a count for them so you know where your completion tokens went.

How reasoning tokens are billed

completion_tokens_details.reasoning_tokens reports the count, but reasoning tokens are not a separate line item. They are already included in completion_tokens, and billed at the same completion rate as any other output token:

cost = billable_prompt × prompt_price
     + cached_tokens    × cache_read_price
     + completion_tokens × completion_price     ← reasoning tokens are already inside this

See How costs are calculated. There is no separate "reasoning price" — GET /models reports an internal_reasoning pricing field for OpenAI-shape compatibility, but for us it is always "0".

After settlement, the count is also available from GET /generation as native_tokens_reasoning.

The reasoning request parameter

reasoning is not one of our routing keys, so if you send it, it is forwarded upstream exactly as given, the same as temperature or tools:

json
{
  "model": "google/gemma-4-26b-a4b",
  "messages": [{ "role": "user", "content": "..." }],
  "reasoning": { "effort": "high" }
}

Because neither of our models implements it, one of two things happens, entirely decided by the serving engine: the field is silently ignored, or the request errors. We do not translate reasoning.effort / reasoning.max_tokens into anything, and we do not validate them. If you are porting code from a gateway that supports configurable reasoning effort, expect this parameter to be a no-op here rather than to error loudly — check GET /models (below) before depending on it.

Discovering support per model

GET /models exposes a reasoning object on entries that support it:

json
{
  "id": "some/future-reasoning-model",
  "reasoning": {
    "mandatory": false,
    "supported_efforts": ["high", "medium", "low"],
    "default_effort": "medium"
  }
}

For a model with no reasoning capability — both of ours, today — reasoning is null:

bash
curl -s "https://openrouter.myip.co.kr/api/v1/models" | jq '.data[] | {id, reasoning}'
json
{ "id": "google/gemma-4-26b-a4b", "reasoning": null }
{ "id": "lgai/exaone-4.0-32b", "reasoning": null }

Treat reasoning: null as "don't send a reasoning parameter to this model" rather than assuming a default behaviour.

Excluding reasoning from the response

If a future catalog model does emit reasoning content in the response (typically a reasoning field alongside content on the message), reasoning.exclude: true in the request is the conventional way to ask an engine to drop it from the reply while still counting and billing the tokens it used. This, too, is passed through unvalidated — whether an engine honours it is a property of that engine.

Why this page exists despite having no reasoning models today

Two reasons:

  1. The billing path already handles it correctly. reasoning_tokens flows through normalizeUsage() and is folded into completion_tokens for pricing purposes regardless of which model produced it — the moment a reasoning-capable model is added to the catalog, no billing code changes.
  2. You may be sending reasoning already. If your client code targets multiple gateways, or you copied a request body from openrouter.ai documentation, it likely already includes a reasoning block. Knowing that it is inert here — rather than silently mis-costing your requests — is the useful fact.

Última atualização: 5 de set. de 2026