Reasoning Controls

Which models accept a reasoning-effort setting, what to send, and what the marketplace changes before the request reaches the provider.

Capability Discovery

GET /v1/models is the capability surface, public and unauthenticated, and the only place per-model reasoning support is published.

  • supported_parameters lists the knobs: reasoning_effort, reasoning, include_reasoning.
  • supported_features often contains reasoning, but not always: some rows accept a reasoning parameter without declaring the feature. Treat supported_parameters as the authoritative signal and supported_features as a hint.
bash
# Models accepting reasoning_effort
curl -s https://api.surplusintelligence.ai/v1/models \
  | jq -r '.data[] | select((.supported_parameters // []) | index("reasoning_effort")) | .id'

# What one model accepts
curl -s https://api.surplusintelligence.ai/v1/models \
  | jq '.data[] | select(.id=="claude-opus-5")
      | {id, supported_parameters, supported_features}'

A 2026-09-07 snapshot returned 41 models accepting reasoning_effort, 114 accepting reasoning, and 112 listing include_reasoning. Counts change; read the endpoint.

Request Shapes

Two distinct spellings exist, and they are not interchangeable.

SpellingShapeExample
reasoning_efforttop-level string"reasoning_effort": "high"
reasoningtop-level object, fields defined by the provider"reasoning": {"effort": "high"}

Send whichever the model's supported_parameters lists. The marketplace forwards the spelling as sent and does not translate between them, with one exception noted in the adaptation table below.

bash
curl https://api.surplusintelligence.ai/v1/chat/completions \
  -H "Authorization: Bearer inf_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "messages": [{"role": "user", "content": "Prove that sqrt(2) is irrational."}],
    "reasoning_effort": "high"
  }'

Accepted Effort Values

No per-model enumeration of accepted values is published, on this API or on the model row. The provider is the authority on which strings its model takes.

Fixed is the ladder the marketplace uses when repairing a rejected value: none, minimal, low, medium, high, xhigh, max. That is a repair ordering, not a guarantee that a given model accepts all seven.

When a provider rejects a value, the marketplace can read the provider's error, select the nearest supported value named in it, and retry the same seller rather than discarding the reasoning intent; it never selects none that way. This repair path is gated by ADAPTER_REPAIR, which ships off, and it only fires on error phrasings it recognizes. When it does not fire, the provider's rejection surfaces or the router moves to another seller with the value unchanged.

Marketplace Adaptations

Request parameters are forwarded by a deny-list: anything that is not a credential, an SSRF vector, or money and tenancy truth reaches the provider by default. A reviewed policy then adapts reasoning parameters where a provider or model is known to reject them.

ChangeCondition
include_reasoning removedAlways, on the chat wire (internal reason code unsupported-knob-stripped)
reasoning_effort droppedThe resolved model's supported_parameters omits it. An unknown model is left alone (internal reason code model-contract-param-stripped)
temperature, top_p, presence_penalty, frequency_penalty, parallel_tool_calls, logprobs, top_logprobs, logit_bias, stop, reasoning removedModel tagged as a reasoning model, served by OpenAI direct
logprobs, top_logprobs removedReasoning model served through OpenRouter
reasoning_effort forced to "none"Six named gpt-5.6 ids served by OpenAI direct with tools present. The model applies a default effort that collides with tool calling, so dropping the parameter does not help. No marketplace offer currently maps those ids to OpenAI direct, so in practice this protects BYOK routes rather than marketplace traffic
reasoning_effort moved to reasoning.effortServed by Concentrate, which understands only the nested spelling. When both are sent, the flat one is dropped instead

Reason codes above are internal labels recorded against the request. They are not returned to the caller: the wire carries the affected parameter name in X-SI-Adapted-Params, never the reason code.

Two further repairs happen reactively, after a provider rejects the request: the nearest-value clamp described above, and a type coercion when a provider reports that it expected a boolean and received a string (a client that stringifies every value sends "true" where a boolean belongs).

Adaptation Disclosure

Parameters the marketplace changed are named in a response header:

X-SI-Adapted-Params: reasoning_effort,include_reasoning

The header is per-request and is the first thing to check when a reasoning setting appears to have had no effect. It is not a complete audit of the outgoing request: see Parameter Compatibility for what it omits. It accompanies the routing headers identifying the serving rail: x-si-served-by, x-si-provider-family, x-si-marketplace-status, x-si-marketplace-attempts, x-si-routing-decision-ms.

Known Limitation: Per-Model, Not Per-Offer

supported_parameters is a property of the model row, not of the offer serving a given request. Two sellers of the same model, on different upstream providers, can disagree about which reasoning parameters and effort values they accept, and no API surface exposes that difference. No endpoint enumerates the accepted effort values for a given model or provider.

Until such a surface exists, the reliable pattern is:

  1. Look up supported_parameters for the model.
  2. Pin the route with a provider hint, or use a BYOK priority provider, so one provider answers every time.
  3. Read X-SI-Adapted-Params on a real response to see whether the parameter was altered.

Reasoning Tokens and Billing

Reasoning models bill hidden reasoning tokens as output tokens. Providers report them separately under usage.completion_tokens_details.reasoning_tokens where they report them at all, and the marketplace records that figure, but the tokens are already inside completion_tokens and are charged at the output rate. A separate reasoning rate is a per-offer field rather than a model property, and no catalogued offer sets one today.

Raising reasoning_effort therefore raises cost. Setting a reasoning parameter does not guarantee that reasoning text is returned: many models reason without exposing the trace. See Pricing.

See Also