Reasoning

One reasoning parameter for every model, with thinking you can read, stream and send back.

Reasoning models think before they answer. Every provider spells that differently: OpenAI and current Claude models take an effort word, older Claude models take a token budget, Google takes a nested thinking configuration. Kontinent accepts one shape and translates it.

json
{
  "model": "bedrock/claude-sonnet-5",
  "messages": [{ "role": "user", "content": "Is 9.11 larger than 9.9?" }],
  "reasoning": { "effort": "high" }
}
FieldTypeMeaning
effort"minimal" | "low" | "medium" | "high"How hard to think. On effort-based models (current Claude, Azure) it is passed through if the model lists it in supported_efforts; otherwise the model's default effort applies. On the older budget-based Claude models it becomes a share of max_tokens (high ≈ 80 %, medium ≈ 50 %, low ≈ 20 %).
max_tokensintegerAn exact thinking budget, for models that support one. Clamped to 1024–128000.
excludebooleanStill think, but do not return the thoughts.
enabledbooleanfalse switches thinking off where the model allows it.

The legacy boolean include_reasoning: true is still accepted and means reasoning: { enabled: true }.

On the budget-based models (five older Claude models on Bedrock: Haiku 4.5, Sonnet 4.5, Opus 4.5, Opus 4.6 and Sonnet 4.6) reasoning.max_tokens and max_tokens are resolved together: the budget is clamped to 1024–128000 and the answer always keeps at least 1024 tokens of room above it. If your max_tokens is too small to hold both, the budget is reduced first. Your cap is respected wherever it can be.

Gemini's thinking budget is forwarded as you set it, because Google applies its own per-model limits and enforces them itself. On effort-based models (every other Claude model, on Bedrock and Vertex, and Azure) reasoning.max_tokens has no equivalent and is ignored.

Which models reason

GET /v1/models says so twice: the flat supported_parameters list every model carries, and, for models that reason, a reasoning object with the detail. Models that do not reason omit the object entirely and omit reasoning from the list.

json
{
  "id": "bedrock/claude-sonnet-5",
  "supported_parameters": ["max_tokens", "temperature", "top_p", "stop", "stream", "tools", "tool_choice", "reasoning", "include_reasoning"],
  "reasoning": {
    "supported_efforts": ["low", "medium", "high"],
    "default_effort": "medium",
    "supports_max_tokens": false,
    "mandatory": false
  }
}

mandatory: true means the upstream refuses to switch thinking off (Azure's GPT-5 and GPT-6 families and o-series, Gemini 2.5 Pro). For those models enabled: false is ignored rather than answered with an error.

Reading the thoughts

Every response carries thinking twice, on purpose:

  • reasoning: a plain string you can concatenate and print.
  • reasoning_details[]: the structured form, which is what you send back to continue a thinking conversation.

Non-streaming:

json
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "No — 9.9 is larger.",
      "reasoning": "Compare the tenths: 0.11 vs 0.9…",
      "reasoning_details": [{
        "type": "reasoning.text",
        "text": "Compare the tenths: 0.11 vs 0.9…",
        "signature": "EqoBCkgIA…",
        "format": "anthropic-claude-v1",
        "index": 0
      }]
    }
  }]
}

Streaming: thinking arrives before the answer, in the same delta a client already reads.

data: {"choices":[{"delta":{"role":"assistant","reasoning":"Compare the ","reasoning_details":[{"type":"reasoning.text","text":"Compare the ","index":0}]}}]}

data: {"choices":[{"delta":{"reasoning":"tenths…","reasoning_details":[{"type":"reasoning.text","text":"tenths…","index":0}]}}]}

data: {"choices":[{"delta":{"reasoning_details":[{"type":"reasoning.text","signature":"EqoBCkgIA…","index":0}]}}]}

data: {"choices":[{"delta":{"content":"No — 9.9 is larger."}}]}

data: {"choices":[],"usage":{"prompt_tokens":19,"completion_tokens":214,"total_tokens":233}}

data: [DONE]

Detail types

typeContainsNotes
reasoning.texttext, sometimes signatureThe model's thinking. On current Claude models this is Anthropic's summary of the thinking, not the raw chain of thought. The signature is an integrity token; keep it.
reasoning.summarysummaryA provider-written précis, for models that never expose raw thoughts.
reasoning.encrypteddataThinking that exists and may not be read. Never accompanied by plaintext.

Redacted thinking

Some models, Azure's GPT-5 and o-series in particular, do the thinking and return only an opaque blob. Kontinent reports it as reasoning.encrypted with no text.

json
{ "type": "reasoning.encrypted", "data": "gAAAAAB…", "format": "openai-responses-v1", "index": 0 }

This is deliberate: we never invent readable thoughts for a model that did not provide them, and we pass the blob on to you rather than hiding it. Sending it back has no effect on Azure, though: the gateway removes reasoning_details before a request goes to an OpenAI-compatible provider. Only Claude's thinking blocks, including redacted ones, are replayed.

Continuing a thinking conversation

Send the assistant turn back with its reasoning_details attached:

json
{
  "model": "bedrock/claude-sonnet-5",
  "reasoning": { "effort": "high" },
  "messages": [
    { "role": "user", "content": "Is 9.11 larger than 9.9?" },
    {
      "role": "assistant",
      "content": "No — 9.9 is larger.",
      "reasoning_details": [{ "type": "reasoning.text", "text": "Compare the tenths…", "signature": "EqoBCkgIA…", "format": "anthropic-claude-v1", "index": 0 }]
    },
    { "role": "user", "content": "And 9.11 vs 9.099?" }
  ]
}

Details are forwarded to providers that can verify them and dropped for those that cannot. An Anthropic signature means nothing to an OpenAI deployment, and sending it would be an error rather than a continuation. Unsigned thinking is dropped too: Claude refuses thinking it cannot attribute to itself, so replaying it would fail the request.

Hiding the thoughts

exclude: true asks the model to think and strips the thinking from the response.

json
{ "reasoning": { "effort": "high", "exclude": true } }

Counting them

Where a provider separates the thinking share of the output, it is reported as usage.completion_tokens_details.reasoning_tokens. The key is omitted rather than zeroed when a provider does not report one. Anthropic counts thinking inside output_tokens and never breaks it out, and a zero would claim the model did not think.

Thinking tokens are billed whether you read them or not. They are output tokens the model generated. exclude is about what your UI shows, not about cost.

Streaming API reference