max_completion_tokens and Token Budget
On this page
Lesson rewritten November 3, 2026 based on the xAI API reference (Chat Completions and Responses), the Reasoning guide, and xAI best practices:
max_completion_tokensandmax_output_tokenscap only the visible response—reasoning tokens and function call tokens do not count toward this limit—and default to 128,000. The previous version claimed the opposite and sized the cap based on reasoning; it also set an effort ongrok-4.20-0309-reasoning, which does not accept it. Sources: Chat Completions · Responses · Reasoning.
What the cap actually limits
For a reasoning model, you might think the output cap shares its budget between thought and response. That is not the case at xAI. The API reference is explicit: max_completion_tokens (Chat Completions) and max_output_tokens (Responses API) apply only to visible output tokens; reasoning tokens and function call tokens are not counted.
max_completion_tokens → visible response only
reasoning tokens → outside cap, set by effort
Without a value, this cap defaults to 128,000 tokens. As for the old max_tokens, it is deprecated in favor of max_completion_tokens.
Steering reasoning: effort, not the cap
Since the cap does not touch reasoning, effort regulates the quantity. On grok-4.7, grok-4.6, and grok-4.5, the parameter is reasoning_effort in Chat Completions and reasoning.effort in the Responses API; it defaults to high, accepts low and medium, and xhigh from Grok 4.6 onward. Reasoning cannot be disabled.
grok-4.20-0309-reasoning does not take this parameter: it always reasons, and its variant grok-4.20-0309-non-reasoning responds without reasoning. On grok-4.20-multi-agent, finally, effort does not set reasoning depth but the number of agents mobilized (4 or 16).
response = client.chat.completions.create(
model="grok-4.7",
reasoning_effort="low", # simple task: little reasoning
messages=[{"role": "user", "content": "Classify this ticket: billing, access, or bug?"}],
)
print(response.usage.completion_tokens_details.reasoning_tokens)
The number of reasoning tokens appears in the response usage: usage.completion_tokens_details.reasoning_tokens in Chat Completions, usage.output_tokens_details.reasoning_tokens in the Responses API. They are part of the billed tokens: so it is effort, not the output cap, that weighs on this line item.
Sizing the output cap
The cap only serves to bound the length of the response itself. xAI best practices give a simple rule: set it above the longest response you expect, or leave its default value of 128,000 tokens. A cap that is too tight cuts the visible response, regardless of reasoning effort.
| Expected response | Reasonable output cap |
|---|---|
| A label, a number | a few dozen tokens |
| A paragraph | 500 to 1,000 tokens |
| A structured report | several thousand tokens |
| No precise idea | the default value |
Detecting truncation
When the visible response hits the cap, Chat Completions returns "length" in finish_reason instead of "stop", and the Responses API returns an incomplete status. You can detect this situation and retry with a higher cap:
response = client.chat.completions.create(
model="grok-4.7",
messages=[{"role": "user", "content": question}],
max_completion_tokens=2000,
)
if response.choices[0].finish_reason == "length":
# Visible response was cut: retry with a higher cap
response = client.chat.completions.create(
model="grok-4.7",
messages=[{"role": "user", "content": question}],
max_completion_tokens=8000,
)
Do not confuse with the context limit
The output cap is independent of the model’s context window—500,000 tokens for grok-4.7, 1 million for grok-4.20-0309-reasoning—which bounds the entire conversation. And a deep reasoning request can take several minutes: xAI recommends allowing at least 900 seconds per request and preferring streaming.
Key takeaways
max_completion_tokensandmax_output_tokenscap only the visible response: reasoning does not count toward this- Without a value, the output cap defaults to 128,000 tokens;
max_tokensis deprecated - Reasoning quantity is set by effort (
reasoning_effortorreasoning.effort) on grok-4.5 to 4.7;grok-4.20-0309-reasoningdoes not have this - Reasoning tokens appear in usage and are part of the bill
- A cut response is detected by
finish_reason: "length"or theincompletestatus