You are about to ship a feature that calls GPT-5.5 per request. Walk through how you estimate the token cost before launch.
Resolve encoding via `encoding_for_model('gpt-5.5')` (returns `o200k_base`), encode the full prompt (system + tools + user + per-message overhead), multiply by prices, and validate against `usage.prompt_tokens`.
Think of an Uber ride. The fare is per mile, but the meter starts at pickup, not when you sit down at your destination. To estimate the fare you need to know the right rate card (which depends on the city), the actual distance the car will cover (not just the part you remember), and a way to check the estimate against the real receipt. Estimating API cost is the same. You pick the encoding for the specific model (the rate card), tokenize everything the API will send through the model (the full distance), and confirm against the response's usage field (the receipt).
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Per call cost estimation looks like simple multiplication: tokens times price. The math is trivial; the work is making sure the token count is right. Most pre ship cost estimates miss the mark not because the price was wrong but because the estimator counted only part of what the API actually sends through the model.
This explanation walks the five step workflow, names the specific encoding and counting calls for the 2026 model families you are most likely to hit, and closes on the validation step that catches the regressions a static estimate cannot.
Step 1: resolve the encoding by model name
The encoding is a model property. tiktoken.encoding_for_model('gpt-5.5') returns the o200k_base encoding, which is the encoding the model was trained with and which the API uses to count input tokens for billing. Calling tiktoken.get_encoding('cl100k_base') directly works but is fragile; cl100k is the GPT-4 era encoding and using it on an o200k model produces wrong counts that drift by 5 to 15 percent depending on content mix.
The pattern that holds across model upgrades is to always resolve by model name. When you upgrade from GPT-4o to GPT-5.5, both happen to use o200k_base so the encoding does not change. When you upgrade from a cl100k_base model to an o200k_base model, the encoding changes and resolving by model name catches the change automatically.
For Anthropic models, use client.messages.count_tokens(model=..., messages=...). Anthropic does not expose its tokenizer the way OpenAI does, so the only authoritative count is the server side count returned by this endpoint. For Gemini, use model.count_tokens(...) on the Vertex SDK. For open weight models (Llama 4, Qwen 3, DeepSeek V4), AutoTokenizer.from_pretrained(...) gives you the canonical tokenizer.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
import json
import tiktoken
# Step 1: resolve the encoding by model name
enc = tiktoken.encoding_for_model('gpt-5.5') # o200k_base
# Step 2-3: assemble and count
system_msg = "You are a helpful assistant."
tool_schema = {"name": "search", "parameters": {"q": "string"}}
user_msg = "Find papers on RoPE scaling."
per_message_overhead = 3 # OpenAI chat completion accounting
input_tokens = (
len(enc.encode(system_msg)) + per_message_overhead
+ len(enc.encode(json.dumps(tool_schema)))
+ len(enc.encode(user_msg)) + per_message_overhead
)
# Step 4: estimate output (use a measured median)
estimated_output_tokens = 400
# Step 5: cost (per 1k token prices in 2026; replace with current)
INPUT_PRICE = 0.0025
OUTPUT_PRICE = 0.010
estimated_cost = (
input_tokens / 1000 * INPUT_PRICE
+ estimated_output_tokens / 1000 * OUTPUT_PRICE
)
# Validate: send a real call and compare usage.prompt_tokens to input_tokens| Model family (2026) | Encoding | How to count input |
|---|---|---|
| GPT-5.5 | o200k_base | `tiktoken.encoding_for_model('gpt-5.5')` + `.encode()` |
| GPT-4 era (4o, 4-turbo) | o200k_base / cl100k_base | Resolve via `encoding_for_model` per specific model |
| Claude Opus 4.7 | Anthropic internal | `client.messages.count_tokens(...)` |
| Gemini 3.1 Pro | Google internal | `model.count_tokens(...)` on the Vertex SDK |
| Llama 4 / open weight | Model specific | `AutoTokenizer.from_pretrained(...).encode(text)` |
Real products, models, and research that use this idea.
- OpenAI GPT-5.5: `tiktoken.encoding_for_model('gpt-5.5')` returns `o200k_base`; every response carries `usage.prompt_tokens` and `usage.completion_tokens`.
- Anthropic Claude Opus 4.7: `client.messages.count_tokens(model='claude-opus-4-7', messages=[...])` returns the server side input token count without consuming a generation.
What an interviewer would ask next. Try answering before peeking at the approach.
QIf your estimate disagrees with `usage.prompt_tokens` by 20 percent, what are the first three things you check?
First, the encoding (cl100k_base vs o200k_base mismatch). Second, whether tool schemas are being counted (the SDK serializes them, the estimator might not). Third, per message overhead and chat template wrappers, which add a small but real per message cost.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Estimating cost from `len(user_message.split())` only. You miss the system message, the tool schemas, the per message overhead, and the chat template wrappers, all of which contribute to the billed input tokens.
60 second bullets to scan on the way to the call.
Pick the encoding via
tiktoken.encoding_for_modeland name the function's return value for GPT-5.5List the prompt components that contribute to input tokens beyond the user message
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.