Realtime TTS-2 is live. Built for realtime conversation that feels human. Read the Realtime TTS-2 announcement

Text generation

Reasoning

Control how much a model reasons before it answers with reasoning_effort on Inworld Inference, and read reasoning text and token usage in the response.

Reasoning models think through a problem before they answer. Set reasoning_effort to control how much reasoning a model does on Inworld Inference. The router translates it to each provider's control: reasoning effort on OpenAI, thinking on Anthropic, and thinking configuration on Google.

Set the reasoning effort

cURL
curl --request POST \
  --url https://api.inworld.ai/v1/chat/completions \
  --header "Authorization: Basic $INWORLD_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "openai/gpt-5",
    "messages": [
      {"role": "user", "content": "A bat and a ball cost $1.10. The bat costs $1 more than the ball. How much is the ball?"}
    ],
    "reasoning_effort": "high"
  }'

reasoning_effort accepts none, minimal, low, medium, high, xhigh, and max, in any letter case. Higher values give the model more room to reason, which costs more output tokens and takes longer. none turns reasoning off on models that allow it.

Each model supports its own range of levels. On OpenAI, Anthropic, Google and Inworld-hosted models, a level the model does not offer is mapped to one it does rather than rejected. An unrecognized value is ignored.

Without reasoning_effort or a budget, each model uses its own default:

  • On Inworld-hosted models, reasoning is off unless you ask for it.
  • On Anthropic models, reasoning is off unless you ask for it, except on Claude models that always reason. On those, none does not turn reasoning off. This matters for forced tool calls, which Claude models accept only while reasoning is off.
  • Other models use the provider's default.

Set a token budget

To cap reasoning in tokens instead of by level, send one of these. The router accepts them at the top level of the request or inside extra_body:

ParameterExample
reasoning{"effort": "high", "max_tokens": 4000}
thinking{"type": "enabled", "budget_tokens": 4000}
max_thinking_tokens4000

With the OpenAI SDK, pass them through extra_body:

Python
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Plan a three-step migration."}],
    extra_body={"reasoning": {"max_tokens": 4000}},
)

When more than one is present:

  • reasoning_effort takes precedence over reasoning.effort.
  • For the budget, reasoning.max_tokens takes precedence over thinking.budget_tokens, which takes precedence over max_thinking_tokens.
  • A top-level parameter takes precedence over the same parameter in extra_body.

You can combine an effort level with a budget. On Anthropic models that take a budget, it must be at least 1,024 tokens; a smaller budget returns 400. Some Claude models do not take a budget and decide for themselves how much to reason; on those, the router sends the request without it.

Models that do not support reasoning

If a model does not support reasoning effort, the router drops the parameter and still serves the request. A warning in metadata.attempts[].warnings tells you that the parameter had no effect on that attempt.

Read the reasoning

When the provider returns reasoning text, it is in message.reasoning, next to message.content:

json
{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "The ball costs $0.05.",
        "reasoning": "Let the ball cost x. Then the bat costs x + 1.00..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 32,
    "completion_tokens": 214,
    "total_tokens": 246,
    "completion_tokens_details": {"reasoning_tokens": 192}
  }
}
  • With stream: true, reasoning text arrives in delta.reasoning. See Streaming.
  • Reasoning tokens are counted in usage.completion_tokens_details.reasoning_tokens, which is present when the count is above zero.
  • Not every provider returns reasoning text. A model can reason, and report reasoning tokens, without exposing what it reasoned.
  • To leave the reasoning text out, send "reasoning": {"exclude": true} (in extra_body with the OpenAI SDK). Only Anthropic models act on it; they still reason and bill reasoning tokens. Other models ignore it and return reasoning text as usual.

The router ignores a reasoning field on assistant messages you send back: it is dropped, not rejected. You can send an assistant message back unchanged, as tool calling asks, but reasoning from an earlier turn is not carried into the next request.

Reasoning on other APIs

Next steps