Skip to content

Request id আর debugging

Tokens-এর প্রতিটা response-এ যে request id header থাকে, সেটা support-কে কীভাবে জানাবেন, কী log করবেন, curl দিয়ে fail হওয়া call কীভাবে আবার চালাবেন, আর error body ও usage page কীভাবে পড়বেন।

Markdown-এ দেখুন
এই পাতায়

কোনো request fail করলে, বা খরচ আশার চেয়ে বেশি হলে আপনার দরকার ঠিক ওই call-টাকে আঙুল দিয়ে দেখানো। Tokens-এ প্রতিটা response-এ একটা request id থাকে, আর যে request-এর বিল হয়েছে তার জন্য usage page-এ একই id-সহ একটা row তৈরি হয়। এই পেজে দেখবেন id কোথায় পাবেন, তার আশপাশে আর কী log করবেন, app-এর failure কীভাবে এমন curl command বানাবেন যা যে কেউ চালাতে পারে, আর কী ঘটেছে তা বলে দেওয়া দুটো জায়গা (error body আর usage page) কীভাবে পড়বেন।

Request id header#

/v1-এর প্রতিটা response-এ, সফল হোক বা error, এই header-গুলো থাকে:

HeaderValue
x-tokens-request-idএই request-এর জন্য gateway-র id (একটা UUID)। এটা সব সময় Tokens-ই বানায়। Support-কে এটাই জানাবেন।
x-request-idআপনি যে x-request-id পাঠিয়েছিলেন হুবহু সেটাই। না পাঠালে ওপরের id-টাই
x-trace-idসফল inference response-এ: x-tokens-request-id-এর মতোই একই মান

Error body-তেও id-টা request_id নামে থাকে। /v1/chat/completions, /v1/responses আর OpenAI format-এর বাকি endpoint-এ সেটা error-এর ভেতরে থাকে। /v1/messages Anthropic-এর error format ব্যবহার করে, তাই সেখানে request_id থাকে body-র একদম ওপরের স্তরে, error-এর পাশে:

json
{
  "error": {
    "message": "Prepaid wallet balance is insufficient for this request.",
    "type": "insufficient_quota",
    "code": "insufficient_credits",
    "param": null,
    "request_id": "8f0c7a4e-2b1d-4c55-9a51-3f7e2d9b6c10"
  }
}
json
{
  "type": "error",
  "error": {
    "type": "billing_error",
    "message": "Prepaid wallet balance is insufficient for this request.",
    "code": "insufficient_credits"
  },
  "request_id": "8f0c7a4e-2b1d-4c55-9a51-3f7e2d9b6c10"
}

কয়েকটা কথা মনে রাখবেন:

  • Tokens provider-এর header পাস করে না। শুধু content type, cache-control, retry-after, x-request-id আর x-tokens-* header আপনার কাছে পৌঁছায়। model-এর নিজের provider-এর request id কখনো দেখতে পাবেন না, তাই Tokens-এর id-টাই জানান।
  • Id আসে header-এর সাথেই। Streaming-এ প্রথম token আসার আগেই এটা পাওয়া যায়। call শুরুর সময়ই log করে রাখুন, তাহলে stream পরে মাঝপথে ভেঙে গেলেও id আপনার হাতে থাকবে।
  • আপনার নিজের x-request-id যেমন পাঠিয়েছেন তেমনই ফেরত আসে। এটা দিয়ে আপনার log-এর লাইনের সাথে Tokens-এর id মেলান। প্রতিটা attempt-এর জন্য নতুন একটা পাঠান, user-এর একটা action-এর জন্য একটা নয়। তাহলে retry আর তার প্রথম চেষ্টা আলাদা করে চেনা যায়।
  • আপনার দিকে timeout হলে Tokens-এর id পাবেন না, কারণ কোনো response-ই আসেনি। এই কারণেই পাঠানোর আগে নিজের id-ও log করে রাখা উচিত।
  • SDK-র helper আপনার id দেখাতে পারে, আমাদেরটা নয়। কিছু SDK x-request-id থেকে পড়া একটা request_id দেয়। আপনি নিজের x-request-id পাঠালে ওই মান আপনারই। gateway-র id পেতে raw header থেকে x-tokens-request-id পড়ুন।

Code-এ id পড়ার উপায়#

curl -sS -i 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":"ping"}],"max_tokens":20}' \
  | grep -i "^x-tokens-request-id"

Anthropic SDK-র ক্ষেত্রেও একই header raw response-এ থাকে। সেখানে কীভাবে পৌঁছাবেন, তা প্রতিটা SDK-র নিজের docs-এ আছে। fetch বা requests দিয়ে call করলে response header সরাসরি পড়ুন।

কী log করবেন#

প্রতিটা attempt-এর জন্য একটা structured line-ই যথেষ্ট। response-এর header আসার সময় log করুন, আর পরে কিছু fail করলে আবার।

Fieldকেন
x-tokens-request-idএটা দিয়ে support আপনার request খুঁজে পায়
আপনার নিজের request idcall-টাকে আপনার log আর retry-র ধারার সাথে বেঁধে রাখে
সময়, time zone সহ (UTC)id না থাকলে এটাই ভরসা
Endpoint আর modelchat/completions, messages, আর model id হুবহু
HTTP status আর error.codeকী ঘটেছে। branch করবেন code দেখে, message দেখে নয়
Latency, আর stream হলে প্রথম token আসতে সময়provider ধীর না আপনার client ধীর, তা আলাদা করা যায়
Response-এর usageinput token, cached token, output token, যাতে খরচ ব্যাখ্যা করতে পারেন
Attempt নম্বরretry চেনা যায়
কোন key (নাম, secret কখনোই নয়)একাধিক key থাকলে সঠিকটা খুঁজে পাওয়া যায়

যা log করবেন না:

  • API key, কোনোভাবেই নয়। header-এ নয়, dump করা config-এও নয়।
  • পুরো prompt আর উত্তর, ডিফল্ট হিসেবে। এতে আপনার customer-এর data থাকতে পারে। Tokens নিজেও prompt-এর content রাখে না, রাখে request id ধরে usage metadata, তাই request খুঁজে পেতে id-ই যথেষ্ট। debug-এর জন্য body log করলে retention ছোট রাখুন আর স্পর্শকাতর অংশ মুছে দিন।

Support-কে id জানানোর নিয়ম#

Support-এ ticket খোলার সময় এগুলো দিন:

  1. x-tokens-request-id। সমস্যাটা বারবার হলে একাধিক id।
  2. কখন ঘটেছে, time zone সহ।
  3. Endpoint আর model id।
  4. HTTP status আর error.code। বিলের প্রশ্ন হলে কত কাটা উচিত ছিল বলে আপনি আশা করেছিলেন।
  5. সমস্যাটা আবার ঘটানো যায় কি না, আর হাতে থাকলে curl command (পরের অংশে আছে)।

API key কখনো দেবেন না। Id থেকেই support আপনার call-এর usage metadata খুঁজে পায়। বাকি প্রক্রিয়া সাহায্য পাওয়ার পেজে আছে, আর সবার জন্যই কিছু ভাঙা কি না তা status page-এ দেখা যায়।

curl দিয়ে fail হওয়া request আবার চালান#

App-এ request fail করলে app-টাকে ছবি থেকে সরিয়ে দিন। একই রকম fail করা একটা curl command থেকে বোঝা যায় সমস্যাটা আপনার code, configuration, key না অ্যাকাউন্টে।

  1. App যে body পাঠিয়েছিল হুবহু সেটা ধরুন: model, messages, max_tokens, tools আর বাকি সবকিছুর JSON। যে customer-এর লেখা অন্যকে দেখাতে চান না, সেটা মুছে দিন।
  2. একটা file-এ save করুন আর একই key ও একই endpoint দিয়ে পাঠান।
  3. Header আর body আলাদা file-এ রাখুন, যাতে id আর error দুটোই থেকে যায়।
curl -sS -D headers.txt -o response.json -w "HTTP %{http_code}\n" \
  https://tokens.bd/v1/chat/completions \
  -H "Authorization: Bearer $TOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "x-request-id: repro-$(date +%s)" \
  -d @body.json

grep -i "^x-tokens-request-id" headers.txt
jq '.error // .' response.json

Windows PowerShell 5.1-এ curl আসলে অন্য একটা command-এর alias, তাই curl.exe লিখুন। Streaming উত্তর আসতে আসতে দেখতে চাইলে -N দিন আর body-তে "stream": true যোগ করুন।

এরপর একবারে একটা জিনিস বদলে সমস্যা ছোট করে আনুন:

curl call যদি...তাহলে বুঝবেন
একই রকম fail করেসমস্যা request-এ, key-তে বা অ্যাকাউন্টে। error.code পড়ে errors পেজে খুঁজুন
ঠিকঠাক চলেসমস্যা আপনার app-এ: environment-এ অন্য key, বদলে যাওয়া body, কোনো proxy, timeout, বা library-র default
stream ছাড়া চলে, দিলে fail করেমাঝখানে buffering করা কোনো proxy, নয়তো SSE সামলাতে না পারা client। দেখুন streaming
শুধু একটা নির্দিষ্ট model-এ fail করেওই model-এর parameter বা availability-র সমস্যা। GET /v1/models থেকে অন্য একটা চেষ্টা করুন
শুধু tools থাকলে বা body বড় হলে fail করেtool schema, 10 MB body-র সীমা, বা model-এর context window
মাঝে মাঝে fail করেrate limit, নয়তো provider-এর সমস্যা। Retry-After আর status page দেখুন

Key আর base URL ঠিক আছে কি না, তার দ্রুত পরীক্ষা হলো GET /v1/models। এতে কোনো model চলে না, আর এটা আপনার per-minute limit-এও গোনা হয় না।

Error body কীভাবে পড়বেন#

Branch করুন error.code দেখে। message মানুষের জন্য, ওটা বদলে যেতে পারে। Error-এর গড়ন আর code-গুলো errors পেজে আছে। একটা error সংক্ষেপে এভাবে পড়ুন:

অংশকীভাবে পড়বেন
HTTP statusশ্রেণি: 4xx মানে সমস্যা request, key বা অ্যাকাউন্টে, 5xx মানে gateway বা কোনো provider-এর
error.codeঠিক কারণটা। insufficient_credits, window_exhausted, model_not_found ইত্যাদি
error.messageপ্রসঙ্গ: যেমন key যেসব model ব্যবহার করতে পারে তার তালিকা, বা window কখন reset হবে
request_idযেটা support-কে জানাবেন
Retry-After header429-এ কত সেকেন্ড অপেক্ষা করবেন

দুটো জিনিস নিয়ে অনেকে ধাঁধায় পড়েন:

  • Provider-এর error সাধারণ message হয়ে আসে। model-এর provider কোনো request reject করলে বা fail করলে, provider-এর ভেতরের তথ্য ফাঁস না হওয়ার জন্য message বদলে একটা সাধারণ message বসানো হয়। তবে status আর code থেকে কোন ধরনের failure তা বোঝা যায়। provider থেকে 400 এলে আপনার parameter-গুলো দেখুন, আর model সেগুলো support করে কি না দেখুন।
  • 200 পাওয়ার পরও stream fail করতে পারে। Streaming শুরু হয়ে গেলে status আগেই 200 হয়ে যায়। provider মাঝপথে fail করলে connection বন্ধ হয়ে যায় data: [DONE] ছাড়াই (Messages-এ message_stop ছাড়াই), আর কোনো error body আসে না। finish reason ছাড়া শেষ হওয়া stream-কে অসম্পূর্ণ ধরুন, আর শুরুতে log করে রাখা request id কাজে লাগান।

Usage page কীভাবে পড়বেন#

Usage পেজে আপনার সাম্প্রতিক request-গুলো activity table-এ আসে, সবচেয়ে নতুনটা ওপরে:

Columnকী দেখায়
Timerequest কখন record হয়েছে
Usagerequest-এর খরচ
Tokensinput · N cached · output। cached অংশ শুধু থাকলেই দেখায়, আর সেটা cache read আর write মিলিয়ে
Timingrequest-এ কত সময় লেগেছে
Modelআপনি যে model id দিয়ে call করেছেন
Mode/v1 দিয়ে আসা request-এর জন্য api
Statusবিল হওয়া request-এর জন্য COMPLETED
Trace IDrequest id। ক্লিক করলে পুরো মান copy হয়; table-এ শুধু প্রথম আটটা অক্ষর দেখায়

API request-এর Trace ID আর তার x-tokens-request-id একই মান। একটা request খুঁজতে হলে আপনার log থেকে id copy করে এই column-এ খুঁজুন। Table-এ page আছে, তাই পুরোনো request-এর জন্য নিচের per-page selector দিয়ে বেশি row দেখান।

এই পেজ থেকে কী জানা যায় আর কী যায় না:

  • শুধু বিল হওয়া request-ই আসে। Request চলে বিল হয়ে গেলে তবেই gateway usage record করে। চলার আগেই reject হওয়া request (ভুল key, ব্যালান্স নেই, rate limit) বা provider-এ fail করা request-এর কোনো row নেই। এগুলোর ক্ষেত্রে আপনার নিজের log-এ রাখা request id আর error body-ই একমাত্র রেকর্ড।
  • আপনার cancel করা request-ও থাকে। Stream-এর মাঝখানে আপনার client disconnect করলে input আর তত দূর পর্যন্ত তৈরি হওয়া output-এর বিল হয়, আর row-তে সেই সংখ্যাই দেখায়।
  • Estimated badge মানে usage report আসেনি। Provider token-এর হিসাব না পাঠালে Tokens request আর উত্তরের আকার থেকে একটা হিসাব বের করে row-তে চিহ্ন দিয়ে দেয়। আপনার বিল হয় সেই হিসাব ধরেই।
  • Cached token কম খরচের কারণ হতে পারে। লম্বা prompt-এও খরচ কম হলে Tokens column-এর cached অংশ দেখুন। দেখুন prompt caching।
  • ছোট prompt-এ বড় খরচের কারণ সাধারণত এগুলোই: প্রতিটা turn-এ আবার পাঠানো লম্বা কথোপকথনের history, যে model ব্যবহার করে তার জন্য বড় max_tokens, output হিসেবে গোনা reasoning token, একাধিকবার বিল হওয়া retry, বা loop থেকে আসা অনেক request। কোনটা, তা প্রতিটা request-এর token দেখলেই বোঝা যায়।

মোট হিসাব, দৈনিক chart আর plan window-গুলো ব্যাখ্যা করা আছে usage and alerts পেজে। Code থেকে দেখে নিতে চাইলে GET /v1/tokens/usage আপনার window, ব্যালান্স আর key-এর cap ফেরত দেয়, এর জন্য কোনো বিল হয় না।

Debugging-এর ছোট একটা রুটিন#

  1. error.code আর status পড়ুন। code-টা errors পেজে খুঁজুন।
  2. Response থেকে, বা আপনার log থেকে x-tokens-request-id নিন।
  3. সেভ করা body দিয়ে curl-এ আবার চালান। একবারে একটা জিনিস বদলান।
  4. একসাথে কয়েকটা request বা model fail করলে status দেখুন।
  5. প্রশ্নটা খরচ বা token নিয়ে হলে Usage দেখুন।
  6. তারপরও ব্যাখ্যা না মিললে id, সময়, model, status আর code দিয়ে ticket খুলুন।

এই পাতাটা কি কাজে লেগেছে?

এখনো আটকে আছেন? Support ticket খুলুন

আপনার agent set up করতে সাহায্য লাগবে?

Connection tester দিয়ে সংযোগ পরীক্ষা করে নিন, অথবা একটা API key তৈরি করুন।