Token Usage and reasoning_tokens
On this page
Updated November 3, 2026. Based on the xAI Chat Completions API reference:
max_tokensis deprecated in favor ofmax_completion_tokens, which limits only the visible response. Source: Chat Completions.
Understand token billing
Every request to the Chat Completions API is billed based on the number of tokens consumed. The usage object in the response gives you an exact count, which is essential for monitoring costs, optimizing prompts, and sizing your API budgets.
The standard usage object
Here is the structure of the usage object returned with every response:
{
"usage": {
"prompt_tokens": 127,
"completion_tokens": 342,
"total_tokens": 469
}
}
The three basic counters
prompt_tokens: number of tokens in your request (system message + history + new message). This is the “input” side of billing.completion_tokens: number of tokens generated by the model in its response. This is the “output” side.total_tokens: sum of the previous two. This is the total billed for this request.
Impact of history on costs
Because the endpoint is stateless, history is sent with every request. This means prompt_tokens increases with each exchange:
Exchange 1 : prompt_tokens = 50 (system + 1 user message)
Exchange 2 : prompt_tokens = 150 (system + 2 user + 1 assistant)
Exchange 3 : prompt_tokens = 300 (system + 3 user + 2 assistant)
Exchange 10: prompt_tokens = 1500 (system + 10 user + 9 assistant)
For long conversations, the cost of history can quickly exceed the cost of the response itself.
reasoning_tokens: specific to reasoning models
Grok models with reasoning capabilities (such as grok-4.20-0309-reasoning) add an extra field to the usage object:
{
"usage": {
"prompt_tokens": 127,
"completion_tokens": 892,
"total_tokens": 1019,
"completion_tokens_details": {
"reasoning_tokens": 550
}
}
}
What are reasoning_tokens?
reasoning_tokens represent the tokens used by the model for its internal reasoning — the “thinking” it does before producing its final response. These tokens are generated but are not visible in the content field of the response.
In the example above:
- The model generated 892 tokens in total (
completion_tokens) - Including 550 internal reasoning tokens (
reasoning_tokens) - Leaving 342 visible response tokens (892 - 550)
Why this matters
Reasoning tokens are billed like normal completion tokens. For a reasoning model, the visible response may represent only a fraction of the total cost:
usage = response.usage
visible_tokens = usage.completion_tokens - usage.completion_tokens_details.reasoning_tokens
reasoning_tokens = usage.completion_tokens_details.reasoning_tokens
print(f"Visible tokens: {visible_tokens}")
print(f"Reasoning tokens: {reasoning_tokens}")
print(f"Reasoning ratio: {reasoning_tokens / usage.completion_tokens * 100:.0f}%")
It is not uncommon for reasoning tokens to represent 50 to 80% of completion tokens for complex questions.
Cost optimization strategies
Reduce prompt_tokens
- Summarize history: instead of sending the entire conversation, summarize older exchanges
- Limit the system message: a 500-token system prompt is rarely necessary — aim for 100–200 tokens
- Filter messages: send only exchanges relevant to the current question
Control completion_tokens
- Use
max_completion_tokens(max_tokensis deprecated): it limits the visible response, not reasoning - Specify the format: “Answer in 3 sentences” costs less than “Explain in detail”
- Choose the right model: a non-reasoning model is less expensive if the task does not require complex thinking
Monitor costs in production
import json
def log_usage(response, requete_id: str):
usage = response.usage
log = {
"id": requete_id,
"prompt": usage.prompt_tokens,
"completion": usage.completion_tokens,
"total": usage.total_tokens,
}
if hasattr(usage, "completion_tokens_details") and usage.completion_tokens_details:
log["reasoning"] = usage.completion_tokens_details.reasoning_tokens
print(json.dumps(log))
Key takeaways
- The
usageobject containsprompt_tokens,completion_tokens, andtotal_tokens prompt_tokensincrease with each exchange due to the history sent- Reasoning models add
reasoning_tokensincompletion_tokens_details - Reasoning tokens are billed at the output rate but are invisible in the response — their share of the cost depends on the task and effort, so measure it
- Optimize by summarizing history, adjusting reasoning effort, limiting
max_completion_tokens, and choosing the right model