Back to blog

AI for beginnersGuide

Reasoning effort and thinking tokens: why thinking costs more

Thinking tokens are billed as output. What the effort levels mean, what to put in max_tokens so the answer isn't cut off, and how to estimate the bill.

By CheapTokens TeamPublished 7 min read

Chat card: why did a one-line answer cost so much? Because the model thought first, and thinking is billed as output
On this page
  1. What the model does before it answers
  2. Effort: the dial on thinking
  3. The empty-answer trap: thinking counts toward max_tokens
  4. What long reasoning does to the bill
  5. Which effort for which job
  6. Moving an old request: the 400 error
  7. Agents and long chats: pick one level and keep it
  8. Try it on your own request

Your request was one factual question. The answer was three lines. The output counter says thousands of tokens. That is not a bug: before answering, many models think in a hidden scratchpad, and those thinking tokens are billed as output tokens. The effort setting decides how much of that thinking happens, and max_tokens has to leave room for it, or you get a cut-off or empty answer.

What the model does before it answers#

Think of an exam. You can write the answer straight away, or fill a page of rough work first. Rough work often gives a better result on a hard problem, but the paper is not free. Reasoning is that rough work, and it is counted in tokens like everything else.

Anthropic's extended-thinking documentation (checked 23 October 2026) says the thinking tokens are part of the billed output tokens, and the response tells you how many: usage.output_tokens_details.thinking_tokens. Say a response comes back with this usage block (example numbers):

json
"usage": {
  "input_tokens": 480,
  "output_tokens": 2150,
  "output_tokens_details": { "thinking_tokens": 1900 }
}

You are billed for 2,150 output tokens. The thinking took 1,900 of them, so the text you actually read is 2,150 − 1,900 = 250 tokens. The same holds even when the thinking text is not returned to you: it still counts. If you want the difference between input and output spelled out first, start with input vs output tokens.

Effort: the dial on thinking#

In Claude's API the dial is output_config.effort. Anthropic's effort page (checked 23 October 2026) lists five levels: low, medium, high, xhigh, max. Three details matter for a beginner:

  • It affects every output token, not only thinking: text, tool calls and thinking together.
  • It is a behavioural signal, not a strict budget. Lower effort means fewer tokens at the price of some capability; at low effort Claude can skip thinking entirely on a simple problem.
  • The default is medium on Claude Opus 5.5 and Claude Haiku 5.5, and high on most other models that support the parameter. Setting the default explicitly is the same as leaving it out.

Levels are recalibrated per model, so high on one model is not the same amount of thinking as high on another, and not every model accepts every level. In one published video someone ran every effort level of Claude Opus 5.5 on the same motion-graphics task and compared the pictures. It is a good way to see what more thinking buys. It will not tell you your bill, because your task is not theirs.

A request for a simple question, with effort turned down:

json
{
  "model": "claude-opus-5-5",
  "max_tokens": 4000,
  "output_config": { "effort": "low" },
  "messages": [
    { "role": "user", "content": "What is the capital of Australia?" }
  ]
}

The empty-answer trap: thinking counts toward max_tokens#

Here is how this goes wrong. You expect a two-sentence answer, so you set max_tokens to 300. The model starts thinking, spends the 300 on its scratchpad, hits the limit and stops. You get an empty reply or a sentence that ends mid-word, and the stop reason says max_tokens.

The docs are explicit: max_tokens is a hard limit on the total output, thinking plus response text, and thinking counts even when its content is not returned. At high effort and above, Anthropic says to set a large value.

In practice:

  1. Take the length of the answer you want.
  2. Add generous room for thinking. A few thousand tokens is a sensible start for anything above low.
  3. Check the stop reason after the first runs. If it still says max_tokens, raise the limit. If the answer is complete, you can lower it.

The cut-off itself, with finish_reason and the context window, is covered in why an AI answer stops mid-sentence.

What long reasoning does to the bill#

Say you run a support bot with 2,000 tickets a day. Each ticket is about 500 tokens in. A short, direct answer is about 400 tokens out. The same ticket with long hidden reasoning is about 4,000 tokens out. Those are assumptions for the example; for your own numbers see how many tokens a request uses.

Per day that is 2,000 × 500 = 1,000,000 input tokens, and either 2,000 × 400 = 800,000 output tokens or 2,000 × 4,000 = 8,000,000 output tokens. The reader of the ticket sees the same two lines either way. The only thing that moved is the output volume, and output is the side that reasoning inflates.

Daily cost of the support bot, 1,000,000 tokens in, short answers vs long reasoning (live prices)
  • MiniMax-M2.7, long reasoning (8,000,000 out)$1.25
  • DeepSeek-V4-Flash, long reasoning (8,000,000 out)$0.815
  • MiniMax-M2.7, short answers (800,000 out)$0.17
  • DeepSeek-V4-Flash, short answers (800,000 out)$0.095

The arithmetic is the same on any model that bills hidden reasoning: output tokens × the output price. For DeepSeek-V4-Flash that price is $0.10 per 1M output tokens, and its output side is cheaper than OpenRouter's reference price. It also answers up to 32,768 tokens at a time with a 380K context, so a large max_tokens fits. Prices are fixed per model, with no peak hours, and the table above recalculates from the live price list. All prices are on the pricing page; the DeepSeek page has the model details.

Here is a request to send yourself. It is a plain summary task, so you do not need long reasoning, and the limit leaves plenty of room:

bash
curl https://api.cheaptokens.dev/v1/chat/completions \
  -H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-ai/DeepSeek-V4-Flash-0731",
    "max_tokens": 2000,
    "messages": [
      {"role": "user", "content": "Summarize in one sentence: A token is a small piece of text that a model reads and writes, and APIs bill by the token."}
    ]
  }'

In the reply, usage.completion_tokens is what you pay for on the output side, and finish_reason should be stop. If it says length, the limit cut the answer. Getting the key and the first call: docs.

Which effort for which job#

  • A fact, a one-line summary, a label. Lowest effort. This is the case from the start of the article: you do not need the rough work.
  • Everyday writing, a short explanation, a simple edit. The default for the model. Change it only after you see what the answers cost.
  • A tricky bug, a multi-step plan, a math problem. high or above, and a large max_tokens. Here the extra thinking is the point.

When unsure, run the same prompt at two levels, compare the answers, and compare output_tokens. If the cheaper answer is as good, you have your level.

Moving an old request: the 400 error#

Older code controlled thinking with a token budget. On Claude 4.7 and later models (Opus 5.5, Sonnet 5.5, Haiku 5.5, Fable 5.1) that form is rejected with a 400 error. You switch to adaptive thinking and set the depth with effort:

json
// before: returns 400 on newer models
"thinking": { "type": "enabled", "budget_tokens": 8000 }

// after
"thinking": { "type": "adaptive" },
"output_config": { "effort": "medium" }
Old thinking budget on the left, adaptive thinking with effort on the right
The same request before and after the move, per Anthropic's docs, checked 23 October 2026

One more trap: on Opus 5.5 adaptive thinking is always on, and thinking: { "type": "disabled" } returns 400 at every effort level. Haiku 5.5 allows thinking to be disabled at high effort or below. If you want less thinking on Opus 5.5, lower the effort instead of switching it off.

Agents and long chats: pick one level and keep it#

If your prompt is cached, changing the top-level effort between requests invalidates the cache breakpoints for that conversation. For an agent loop or a long chat, choose one level up front. Some models offer per-message effort in beta that keeps the cache, which is worth a look once the basics are in place. Long chats have a second cost driver, covered in why a long chat costs more.

Try it on your own request#

  1. Send your real prompt once and read usage: how many output tokens, and how many of them are thinking.
  2. Lower the effort one step and send it again. Compare the answers and the counts.
  3. Set max_tokens to the answer you want plus room for thinking, and check the stop reason.

Then put your own token counts into the live price table on the pricing page and you have a monthly estimate.