Why your token count is higher than your prompt
A five-word question shows up as thousands of tokens in your usage. That is not a billing bug — here is the breakdown.
2 min · · Updated · tokens · pricing · billing
A common question: "I sent one sentence, why does my usage show two thousand input tokens?" The answer is almost always that you did not send one sentence.
What actually goes to the model
Models hold no state between calls. Everything they "remember" arrives fresh in every request. The bill includes:
The system prompt. In IDEs and agents it is large and you did not write it. Tools like Claude Code send thousands of tokens of instructions with every request.
The whole conversation history. On the tenth message you send the previous nine plus every model reply. Hence the familiar growth curve: 1k, 3k, 7k, 12k tokens for messages of identical length.
Tool definitions. Function JSON schemas travel in full on every request, even when none are called.
File contents. One "look at this file" adds the entire file to your input tokens — and keeps it there for every subsequent step.
Output tokens are not just text either
If the model reasons, that reasoning is billed as output even when you never see it. A three-line answer with thinking enabled easily costs several thousand output tokens.
Cancelled generations are billed too — in full: if you hit stop or drop the stream midway, the gateway still reads the provider's response to the end and charges for the whole generation, not just the part you received.
Where to find the truth
Do not guess — the API returns exact numbers in the usage field of every response:
"usage": {"prompt_tokens": 6499, "completion_tokens": 214, "total_tokens": 6713}Compare that against your mental model of the request. If prompt_tokens is far larger than expected, look for history, a system prompt, or files sitting in context.
The same numbers appear per request in your dashboard's usage history (except cached responses — cache hits are not written to the history).
Cutting the bill
In order of payoff: trim history, stop carrying already-read files in context, reduce the number of attached tools, and lower reasoning depth on simple tasks.
One trait of agent workloads matters here: up to 99% of their tokens are input, not output. Optimising answer length achieves nothing — the savings live where the context grows.
When to contact support
If the usage in an API response and the number in your usage history disagree, that is our problem — send us the request id. In the overwhelming majority of cases the numbers agree, and what differs is the assumption about what was sent.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- opencode agents: setting up roles, models and toolsA custom agent in opencode is a role, a model and a set of permissions. A working config where a cheap model handles routine work and a stronger one edits code.
- OpenAI API Keys in the Open: Why You Should Not Use ThemWhere free keys on GitHub come from, why using them is dangerous for you and for the owner, and how to protect your own key from the same leak.
- GLM API Errors: Why the Request Fails and How to Fix ItA wrong model id, an overflowing 128K context, the key, the balance, limits: the typical causes of GLM API errors and a quick way to find yours.
- Plan mode in Claude Code: plan first, then edit the codeIn plan mode Claude Code reads your code and proposes a plan but edits nothing until you agree. How to enable it, use it and what it costs.