Core APIsReasoning

Reasoning

Use `reasoning_effort` on o-series and DeepSeek-R1 style models. Read `reasoning_content` from the stream.

Reasoning models emit hidden chain-of-thought tokens before they produce the visible answer. CleverRouter exposes a single reasoning_effort knob and a typed reasoning_content field so you don't have to special-case per provider.

At a glance

Wire formatOpenAI reasoning_effort (mapped to provider equivalents)
Recommended modelsdeepseek/deepseek-r1-distill-llama-70b, mistral/magistral-medium
Billed asCompletion tokens (completion_tokens_details.reasoning_tokens)
Latency budgetSeconds (low) → minute+ (high)

Set the effort

reason.ts
import { createCleverRouter } from '@cleverrouter/sdk';

const cr = createCleverRouter({ apiKey: process.env.CLEVERROUTER_API_KEY! });

const res = await cr.chat({
  model: 'deepseek/deepseek-r1-distill-llama-70b',
  reasoning_effort: 'high', // 'low' | 'medium' | 'high'
  messages: [
    {
      role: 'user',
      content: 'Prove that for every prime p > 2, p² mod 24 = 1.',
    },
  ],
});

console.log(res.choices[0]?.message.content);
console.log(res.usage?.completion_tokens_details?.reasoning_tokens);

Effort vs latency vs cost

EffortUse caseTypical latency
lowValidation, simple refactors, lookups2 – 6 s
mediumComplex tasks, multi-step planning6 – 20 s
highProofs, architecture reviews, debugging20 – 90 s

Reasoning tokens cost real money

Hidden thinking tokens are billed at the same rate as visible completion tokens. 'high' can quietly double or triple your bill on long-form questions. Default to 'low'; upgrade only when the problem actually needs it.

Read reasoning content from the stream

Some models stream their chain-of-thought as a separate reasoning_content delta before the answer starts:

const stream = cr.stream({
  model: 'deepseek/deepseek-r1-distill-llama-70b',
  reasoning_effort: 'medium',
  messages: [{ role: 'user', content: 'Hard question.' }],
});

let thinking = '';
let answer = '';

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta;
  if (delta?.reasoning_content) {
    thinking += delta.reasoning_content;
    // typically hidden in UI, shown behind a "Show thinking" toggle
  }
  if (delta?.content) {
    answer += delta.content;
    process.stdout.write(delta.content);
  }
}

How the gateway maps reasoning_effort

The gateway translates the OpenAI-shape reasoning_effort to the provider's equivalent so your code stays portable:

ProviderUnderlying field
OpenAI o-seriesreasoning_effort
Anthropic (via Bedrock)thinking.budget_tokens
DeepSeek-R1 familyreasoning_effort passthrough
Mistral Magistralreasoning.budget

Common gotchas

  • Tensorix Kimi-K2 quirk. This provider emits reasoning_content but sometimes leaves content empty even after the answer finishes. The SDK forwards reasoning_content separately so you can recover the visible text from it if content is missing.
  • Streaming without reasoning_content. Not every reasoning model streams chain-of-thought — some only expose it in non-stream mode under completion_tokens_details.reasoning_tokens.
  • Long-running streams. With high, set { timeoutMs: 120_000 } on the call — the SDK's 60s default will abort mid-thought.