token কত, তার ওপর নির্ভর করে request-এর খরচ কত, সেটা model-এর context window-তে আঁটবে কি না, আর আপনার plan-এর কতটা খরচ হবে। Tokens-এ token জানার দুটো উপায় আছে। একটা counting endpoint, যেটা request পাঠানোর আগেই input-এর size বলে দেয়। আরেকটা প্রতিটা response-এর usage object, যেটা বলে আসলে কত বিল হলো। এই পেজে দুটোই আছে, সাথে দুটোর কোনোটাই হাতে না থাকলে কীভাবে আন্দাজ করবেন সেটাও।
POST /v1/messages/count_tokens দিয়ে token গোনা#
POST https://tokens.bd/v1/messages/count_tokens /v1/messages-এর মতোই body নেয় আর input token-এর সংখ্যা ফেরত দেয়। এটা কখনো model চালায় না, কোনো text-ও তৈরি করে না। এটা Anthropic format-এ কাজ করে, তাই Anthropic SDK-র base URL হিসেবে দিতে হয় শুধু host-টা, অর্থাৎ https://tokens.bd।
curl -i https://tokens.bd/v1/messages/count_tokens \
-H "x-api-key: $TOKENS_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "deepseek/deepseek-v4.1-flash",
"system": "You are a concise senior engineer.",
"messages": [
{"role": "user", "content": "Explain idempotency keys in two sentences."}
]
}'import os
import anthropic
client = anthropic.Anthropic(
base_url="https://tokens.bd",
api_key=os.environ["TOKENS_API_KEY"],
)
count = client.messages.count_tokens(
model="deepseek/deepseek-v4.1-flash",
system="You are a concise senior engineer.",
messages=[{"role": "user", "content": "Explain idempotency keys in two sentences."}],
)
print(count.input_tokens)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://tokens.bd",
apiKey: process.env.TOKENS_API_KEY,
});
const count = await client.messages.countTokens({
model: "deepseek/deepseek-v4.1-flash",
system: "You are a concise senior engineer.",
messages: [{ role: "user", content: "Explain idempotency keys in two sentences." }],
});
console.log(count.input_tokens);response-এ থাকে মাত্র একটা field:
{ "input_tokens": 31 }সংখ্যাটা বোঝানোর জন্য দেওয়া। Tokens-এর সব endpoint-এর মতো এখানেও model বাধ্যতামূলক, তবে max_tokens লাগে না। system, text ও image-সহ messages, আর tools পাঠাতে পারেন, count-এ সবকটাই ধরা হয়। authentication /v1/messages-এর মতোই: x-api-key বা Authorization: Bearer। অন্য জায়গার মতো এখানেও content-type: application/json পাঠান।
নিখুঁত count, না আন্দাজ#
token কীভাবে গোনা হবে সেটা ঠিক করে model, তাই Tokens দুইভাবে উত্তর দেয়:
| কী হয় | কীভাবে বুঝবেন |
|---|---|
| model-টা যে provider-দের মাধ্যমে চলে, তাদের কেউ Anthropic Messages protocol বোঝে। তাই request তার কাছে যায় আর আপনি তার নিজের count পান। | আলাদা কোনো header নেই। |
| model-এর কোনো provider ওই protocol বোঝে না, অথবা যে বোঝে সে down আছে বা 404, 405, 429 বা কোনো 5xx error দিয়েছে। তখন Tokens নিজেই locally গোনে। | response header x-tokens-estimated: true। |
যে model শুধু OpenAI-format provider-এর মাধ্যমে চলে, তার native counting নেই, তাই সে সব সময় আন্দাজই পায়। কোনো সংখ্যা token-পর্যায়ে নিখুঁত ধরে নেওয়ার আগে header-টা দেখে নিন (curl -i ওটা দেখিয়ে দেয়)।
locally যে হিসাব হয়, সেটা ইচ্ছে করেই মোটামুটি। এটা system, messages আর tools-এর text প্রায় চার character-এ এক token ধরে গোনে, প্রতিটা image বা document block-এর জন্য flat 1,600 token যোগ করে, প্রতিটা message-এর জন্য আরও কয়েকটা token ধরে, আর কমপক্ষে 1 ফেরত দেয়। এই সংখ্যাগুলো বদলে যেতে পারে। "এটা আঁটবে তো?" বা "মোটামুটি কত বড়?" জানতে এটা যথেষ্ট, কিন্তু নিখুঁত count নয়। code, JSON আর বাংলার মতো ইংরেজি-ভিন্ন text-এ চার character-এ এক token ধরাটা সবচেয়ে কম ঠিক হয়, কারণ ইংরেজি গদ্যের তুলনায় এগুলোতে প্রতি character-এ সাধারণত বেশি token লাগে। budget ঠিক করার আগে নিজের data মেপে দেখুন (নিচে দেখুন)।
provider যখন forward করে, count তখন Anthropic-এর নিজের endpoint-এর মতোই চলে। Anthropic-এর token counting docs অনুযায়ী, অক্টোবর 2026-এ মিলিয়ে দেখা হয়েছে: count নিজেও একটা আন্দাজ, তাই বিল হওয়া সংখ্যা থেকে সামান্য আলাদা হতে পারে। এটা system prompt, tool, image আর PDF গোনে, আর server tool, MCP connector এবং url বা file ধরনের image ও document source বাতিল করে দেয় (image আর PDF base64-এ পাঠান)। count আবার model-এর tokenizer-এর ওপরও নির্ভর করে, তাই যে model id পাঠাবেন সেটা দিয়েই গুনুন।
Count করতে কত খরচ, আর এটা কিসের হিসাবে ধরা হয়#
- বিল হয় না। count কখনো চার্জ করে না, plan-এর credit খরচ করে না, আর কোনো usage record-ও লেখে না।
- তবু request-এর মতোই যাচাই হয়। counting-ও inference-এর মতো একই admission ধাপ পার হয়। তাই লাগে একটা valid key, এমন model যা আপনার key আর plan call করতে পারে, আর এমন অ্যাকাউন্ট যাতে plan বা Wallet-এর ব্যালান্স আছে। এটা আপনার per-minute request limit-এ গোনা হয় আর চলার সময় একটা concurrency slot ধরে রাখে। usage window শেষ হয়ে গেলে (429
window_exhausted) বা key অন্য model-এর জন্য সীমিত থাকলে counting-ও আটকে যায়।GET /v1/modelsআরGET /v1/tokens/usage-এর মতো এটা rate limit থেকে মুক্ত নয়। rate limits পেজ দেখুন। - একই size-এর সীমা। image-সহ body 10 MB পর্যন্ত হতে পারে।
- Messages endpoint লাগে। gateway-তে Anthropic Messages endpoint বন্ধ করা থাকলে counting 404
anthropic_protocol_disabledফেরত দেয়, তখন নিচের উপায়গুলো ব্যবহার করুন।
এই endpoint-এর error Anthropic-এর error shape-এ আসে, ভেতরে থাকে Tokens-এর code। Messages পেজে এটা বিস্তারিত আছে। code-গুলোর তালিকা errors পেজে।
অন্য endpoint-এর token গোনা#
chat completions, completions, responses বা embeddings-এর জন্য কোনো counting endpoint নেই। তার বদলে এগুলো করুন।
ফেরত আসা usage পড়ুন#
প্রতিটা সফল inference response জানায় provider কত গুনেছে, আর Tokens ঠিক সেটার ওপরই বিল করে:
| Endpoint | সংখ্যাগুলো কোথায় |
|---|---|
/v1/chat/completions | usage.prompt_tokens, usage.completion_tokens, usage.total_tokens; cache করা input জানানো হলে usage.prompt_tokens_details.cached_tokens-এ |
/v1/completions | usage.prompt_tokens, usage.completion_tokens, usage.total_tokens |
/v1/embeddings | usage.prompt_tokens, usage.total_tokens |
/v1/responses | usage.input_tokens, usage.output_tokens |
/v1/messages | usage.input_tokens, usage.output_tokens, সাথে provider জানালে cache-এর field-ও |
stream-এর ক্ষেত্রে chat completions তখনই usage দেয়, যখন আপনি stream_options: {"include_usage": true} দেন। Anthropic-format stream-এ এটা আসে message_start আর message_delta event-এ। বিস্তারিত streaming পেজে। প্রতিটা request-এর খরচ দেখা যায় usage analytics-এ, আর plan-এর window ও Wallet-এর ব্যালান্স কতটা বাকি তা পাবেন GET /v1/tokens/usage-এ (models and usage)।
এক token-এর request দিয়ে মেপে নিন#
লম্বা generation চালানোর আগে chat model-এর জন্য prompt-এর ঠিক size জানতে চাইলে আসল prompt-টা max_tokens 1 দিয়ে পাঠান, আর usage.prompt_tokens পড়ুন:
curl https://tokens.bd/v1/chat/completions \
-H "Authorization: Bearer $TOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4.1-flash",
"messages": [{"role": "user", "content": "Explain idempotency keys in two sentences."}],
"max_tokens": 1
}'এটার বিল হয়: input token আর বড়জোর একটা output token-এর দাম দিতে হয়। এটাও একটা request হিসেবে গোনা হয়। কিছু model খুব ছোট max_tokens নেয় না বা উপেক্ষা করে, তাই 400 এলে একটু বাড়িয়ে দিন। Messages format-এ আরও সস্তায় দেখতে চাইলে ওপরের counting endpoint ব্যবহার করুন।
মোটামুটি নিয়মে আন্দাজ করুন#
তাড়াতাড়ি একটা budget ধরতে, ইংরেজি গদ্যের character-সংখ্যাকে চার দিয়ে ভাগ করুন। gateway নিজের pre-flight check-এও তাই করে: forward করার আগে সে সবচেয়ে খারাপ ক্ষেত্রের খরচ ধরে রাখে, input-এর জন্য request body-র size-কে চার দিয়ে ভাগ করে, আর output-এর জন্য max_tokens (না দিলে 8,192) ধরে। এই reservation নিরাপত্তার জন্য বাড়তি ধরে রাখা অঙ্ক মাত্র, বিল নয়: চার্জ হয় provider-এর জানানো usage-এর ওপর। তবে এর ফলে max_tokens অনেক বড় দিলে, আসল উত্তর ছোট হলেও, টাকার অভাবে বা spend cap-এর কারণে request fail করতে পারে। তাই max_tokens যতটা দরকার তার কাছাকাছি রাখুন। chat completions পেজ দেখুন।
কোনো local tokenizer library শুধু সেই model-পরিবারের জন্যই নিখুঁত count দেয়, যার জন্য সেটা বানানো। অন্য model-এর বেলায় সেটাও আরেকটা আন্দাজ, তাই size ঠিক করতে ব্যবহার করুন, আর সত্যি সংখ্যার জন্য usage object দেখুন।
পাঠানোর আগে দেখে নিন prompt আঁটবে কি না#
prompt-এর token আর max_tokens মিলিয়ে model-এর context window-র ভেতরে থাকলে request আঁটে। context window-র মান catalog-এ model-এর পেজে আছে। নিচের Python helper আগে গোনে, তারপর যতটা জায়গা বাকি তার ভিত্তিতে max_tokens ঠিক করে:
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://tokens.bd",
api_key=os.environ["TOKENS_API_KEY"],
)
CONTEXT_WINDOW = 128_000 # read this from the model's catalog page
messages = [{"role": "user", "content": open("big-file.txt").read()}]
used = client.messages.count_tokens(model="deepseek/deepseek-v4.1-flash", messages=messages).input_tokens
room = CONTEXT_WINDOW - used
if room < 1_000:
raise SystemExit(f"Prompt is {used} tokens; too close to the context window.")
reply = client.messages.create(
model="deepseek/deepseek-v4.1-flash",
max_tokens=min(4_000, room),
messages=messages,
)
print(reply.usage)CONTEXT_WINDOW-এর জায়গায় আপনার model-এর আসল মান বসান। count যদি আন্দাজ হয়, তাহলে বাড়তি জায়গা রাখুন, যেমন 10 শতাংশ।
আরও পড়ুন#
- Messages: যে endpoint-এর body নিয়ে counting কাজ করে।
- Chat completions, Embeddings আর Legacy completions: প্রতিটার
usageobject দেখতে। - Plans and wallet: token কীভাবে credit আর খরচে বদলায়।