What is a token?
A token is a piece of text the model reads or writes: a short word, part of a longer word, a number or a punctuation mark. As a rough guide for English text, 1,000 tokens is about 750 words, or one token is about four characters. Code, other languages and unusual formatting often use more tokens per word. Each model family uses its own tokenizer, so the same text can count slightly differently on different models.
You do not need to count tokens yourself. Every API response includes a usage object with the exact numbers, and the console shows them for every call.
Input tokens vs output tokens
- Input tokens: everything you send in the request, including the system prompt, the full conversation history, any documents or code you paste, and tool definitions.
- Output tokens: everything the model writes back, including reasoning text for models that show it.
Output tokens are usually priced higher than input tokens, often several times higher. So a request that sends a lot and gets a short answer (classification, extraction) is cheap per call, while a request that asks for long text (articles, full files of code) is driven mostly by the output price.
The formula
cost of one call = (input_tokens x input_price + output_tokens x output_price) / 1,000,000
monthly cost = cost of one typical call x calls per day x days
Worked example with example numbers, not real prices: suppose a model costs 3 units per 1M input tokens and 15 units per 1M output tokens. A call with 2,000 input tokens and 500 output tokens costs (2,000 x 3 + 500 x 15) / 1,000,000 = 0.0135 units. At 1,000 calls a day for 30 days, that is about 405 units a month. Replace the example prices with the real ones from the table below.
Real prices now
Estimated from the prices on the models page: 2,000 input tokens and 500 output tokens per chat. The console shows the actual charge.
| Models | Per chat | 1,000 chats |
|---|---|---|
| GEM 3.8 Flash | Rp 4 | Rp 4.434 |
| TT-6 Luna | Rp 11 | Rp 10.642 |
| TT-6.1 Terra | Rp 7 | Rp 7.263 |
| HK-5.5 | Rp 3 | Rp 3.487 |
| GEM 4 Argon | Rp 85 | Rp 84.649 |
| TT-6.1 Sol | Rp 15 | Rp 14.526 |
The live prices are also on the models page. In the console, Usage lists your last 50 calls with model, input tokens, output tokens and the exact cost, so you can check your estimate against real calls.
How to estimate your own bill step by step
- Pick a model from the models page and note its input and output price per 1M tokens.
- Send 5 to 10 realistic requests and read
usage.prompt_tokensandusage.completion_tokensfrom each response (or check Usage). - Average the input and output tokens to get one typical call.
- Put those averages into the formula above to get the cost per call.
- Multiply by your expected calls per day and days per month.
- Add a margin for retries and longer conversations, then top up a little more than that so the balance does not run out mid-month.
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.macloudai.com/v1", api_key=os.environ["MACLOUD_API_KEY"])
r = client.chat.completions.create(
model="gem-3.8-flash",
messages=[{"role": "user", "content": "Summarize: ..."}],
max_tokens=200,
)
print("input tokens:", r.usage.prompt_tokens)
print("output tokens:", r.usage.completion_tokens)
# fill in real prices per 1M tokens from the models page
INPUT_PRICE, OUTPUT_PRICE = 0, 0
cost = (r.usage.prompt_tokens * INPUT_PRICE + r.usage.completion_tokens * OUTPUT_PRICE) / 1_000_000
print("cost of this call:", cost)
Why long conversations get expensive
Chat APIs are stateless: the model does not remember earlier messages, so your app sends the whole conversation again on every turn. If each turn adds about 500 tokens, turn 1 sends 500 input tokens, turn 10 sends about 5,000, and turn 40 about 20,000. The total input over a long chat grows much faster than the number of messages.
Coding agents such as Claude Code and Cursor agent mode are an extreme case, because they also send file contents and command output. That is why a single long agent session can cost more than hundreds of short API calls.
- Start a new conversation when the topic changes.
- Keep only the last few turns, or replace older turns with a short summary.
- Keep the system prompt short; it is resent on every call.
- Send only the parts of a document that the question needs.
What does max_tokens do?
max_tokens is the maximum number of output tokens the model may generate for one reply. It is a ceiling, not a target: you pay for the tokens actually generated, not for the limit. Setting it protects you from runaway answers, for example a loop that keeps writing, or a model that writes three paragraphs when you wanted a single label. If a reply is cut off in the middle, the limit was too low; raise it for that kind of request.
Other ways to spend less
- Use a smaller model for simple jobs and a large one only where quality clearly improves. See which model for which job.
- Ask for short, structured output (JSON with fixed fields) instead of free text.
- Cache answers in your own app for questions that repeat.
- Create one key per project so the usage log shows which project spends what.
Billing is prepaid: you top up a balance, each call is deducted after it finishes, and there is no monthly fee or minimum spend. The balance does not expire while your account is active.
FAQ
Q1How many words is 1 million tokens?
Q2Why are output tokens more expensive?
Q3Am I charged for max_tokens even if the answer is shorter?
Q4Why did my bill jump with long chats?
Q5Where can I see the cost of each call?
More guides
- One API key for Claude, GPT, Gemini and DeepSeek
- How to use Claude Code with a custom API endpoint
- Claude Code API errors and fixes: 401, 403, 404, 429, 5xx
- How to use Cursor with your own API key and base URL
- Claude vs GPT vs Gemini vs DeepSeek: which model for which job
- Add AI to n8n workflows with an OpenAI-compatible API