← Blog

Claude API Max Tokens Parameter: Best Practices

2026-10-23 · 5 min read · SubToAPI Team

If you've ever gotten a response from Claude that stops mid-sentence, or paid more than expected for a short answer, there's a good chance the max_tokens parameter is the culprit. This single field controls both the ceiling on response length and, indirectly, your output cost and latency — so getting it right matters more than most developers assume.

The short answer: max_tokens is a required parameter that sets the upper bound on how many tokens Claude is allowed to generate in a single response. It does not guarantee that many tokens will be produced — Claude stops earlier if it reaches a natural end (stop_reason: "end_turn"). It only guarantees Claude won't go past that number. If Claude is still generating when it hits the limit, the response is cut off and stop_reason becomes "max_tokens". The rest of this article covers how to pick good values, how to detect truncation, and how to tune this per use case instead of hardcoding a number and hoping.

What max_tokens Actually Does

Every Claude API request needs a max_tokens value. It's not a suggestion or a soft target — it's a hard cap on the output. Under the hood:

A common mistake is treating max_tokens as a cost control knob by setting it low across the board. That works, but it also risks silent truncation — the model doesn't know ahead of time how long its answer "should" be, so if you cut it off too early you get incomplete JSON, broken code blocks, or sentences that stop mid-word.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "Summarize this changelog in 3 bullet points."}
    ]
  }'

Choosing a Value: Match It to the Task, Not a Fixed Default

There's no universal "correct" max_tokens. The right value depends entirely on what you're asking Claude to do:

A practical rule: estimate the expected output length, add 20–30% headroom, and use that as your max_tokens. Don't just set it to the model's absolute maximum by default — that increases worst-case latency and gives a buggy prompt more room to run away.

Detecting and Handling Truncation

Always check stop_reason in the response, not just whether a response came back successfully.

{
  "stop_reason": "max_tokens",
  "usage": { "input_tokens": 142, "output_tokens": 1024 }
}

If stop_reason is "max_tokens", the content is incomplete. Depending on the use case, you have a few options:

  1. Increase max_tokens and retry — simplest fix if you have headroom in the context window.
  2. Continue the generation — send the partial response back as context and ask Claude to continue from where it left off. This works well for long-form content but adds a request round-trip.
  3. Redesign the prompt — if truncation happens often, the model may be padding with unnecessary preamble before getting to the actual answer. Tighter instructions ("respond with only the JSON object, no explanation") often shrinks output length more reliably than raising the cap.

For streaming responses, check the final event's stop reason the same way — truncation detection doesn't change whether you're using the standard endpoint or SSE streaming (see /docs/streaming if you're building a token-by-token UI).

max_tokens and Cost

Output tokens are typically priced higher per token than input tokens across most Claude models, so max_tokens has a direct relationship to your bill — but only as a ceiling, not as a guaranteed charge. You're billed for tokens actually generated, not the configured maximum. Setting max_tokens to 4096 "just in case" doesn't cost you anything extra if Claude naturally stops at 300 tokens. The real cost risk is the opposite: a loop or agent that keeps hitting the max and retrying with ever-larger limits, silently escalating spend.

If you're running Claude access through SubToAPI, every request's usage block — input and output token counts — is captured automatically and surfaced in your dashboard alongside your sub_live_ key activity, so you can see exactly where max_tokens settings are driving cost without building your own logging. Check /docs/messages for the full request/response shape, or start with /docs/quickstart if you're setting up your first integration.

A Few Concrete Recommendations

Tuning max_tokens well is less about finding one magic number and more about treating it as part of your prompt design — reviewed and adjusted alongside the prompt itself, not set once and forgotten.

Questions

Does a higher max_tokens make responses longer? No. It only raises the ceiling. Claude still stops naturally at end_turn if it finishes before reaching the limit — a higher value just reduces the risk of truncation.

What happens if max_tokens is too low? The response gets cut off mid-generation, stop_reason returns as "max_tokens", and you may receive incomplete JSON, broken code, or truncated sentences that need a retry or continuation.

Am I charged for the full max_tokens value even if the response is shorter? No. Billing is based on actual output tokens generated, not the configured maximum — max_tokens is a limit, not a reserved or guaranteed charge.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →