What to check before you pick a provider
One chat holds questions with very different costs of error. "Where is my invoice?" can be answered fast. A refund needs an order check and an employee. So map the tasks first, then compare APIs: a smooth demo still breaks when a customer repeats a message, a request times out or an agent needs the whole conversation.
| Check | What you need | Test before launch |
|---|---|---|
| Models and format | IDs from the live catalog, a clear endpoint and error format | Reject unknown IDs at deploy; run one fixture through your SDK and gateway |
| Limits and errors | A limit per key, project or route | Create a separate bot key and hit the limit on purpose; simulate a timeout, rate limit, invalid key and empty balance |
| Reliability | Timeout, retry with a pause, duplicate protection | Cut off the upstream and watch the queue |
| Usage data | Request history and a channel for failures | Match a test request ID to model, duration, status and account |
| Privacy | Control over logged fields and retention | List every field sent to the provider, drop the extras and send a test message with personal-data markers |
| Switching | A second route without rewriting business logic | Change the ID in configuration, not in handler code |
A good provider never hides a refusal behind "try later". The customer gets a code, a request ID and a safe message, and the operator sees the cause in a closed log. The models documentation lists the IDs available through codexkey. Recheck it at every router deploy.
Which model for which support task
This is a route to test, not a ranking. The IDs were checked against the codexkey catalog on 3 and 4 October 2026. Run them on your own anonymized tickets with one acceptance rubric.
| Task | Acceptance check | Model IDs to test |
|---|---|---|
| Topic label and short FAQ | JSON parses, answer stays inside policy | claude-sonnet-5, gpt-6-sol, gpt-6-luna, deepseek-v4-flash |
| Answer from the knowledge base | Follows the source, refuses when data is missing | claude-sonnet-5, gpt-6-sol, gemini-3.7-flash |
| Long conversation or account explanation | Context limit under control; conditions and next steps survive | claude-opus-5-5, gpt-6-astra, gpt-6.1-sol, gemini-3.8-flash |
| Second route for a comparison run | The same fixture gives a reviewable result | claude-fable-5-1, gpt-6-sol, qwen3.8-flash |
| Hard case for an operator | Metadata, timeout, no duplicate ticket on retry; no refund or account change runs on its own | Any model on the approved route, then a human |
Telegram and chat architecture
Keep the Telegram layer thin. It authenticates the chat, normalizes the update and sends the reply. Business rules live in a service that a web chat or an agent console can reuse.
Telegram webhook
-> chat authentication and idempotency
-> support service and knowledge retrieval
-> model router
-> provider gateway
-> policy check and human handoff
-> Telegram response
Inside that service the backend gives the message an internal ID, strips surplus personal data and picks the topic. Knowledge search returns excerpts with the document version and update date. The model gets the question, the excerpts and short answer rules, and a validator checks the format and forbidden actions. If the data falls short, a ticket is created and the user hears honestly that an operator takes over.
Put a queue between the webhook and generation when a reply can outlast Telegram's request window, and store the update ID to refuse a second delivery: users tap twice, networks retry. The bot needs no access to the orders database. When an order must be checked, the backend fetches the minimum fields after authorization and gives the model only what it needs to word the answer.
A server-side call with a request ID
Keep the API key in the runtime environment, never in the browser or a Telegram message. In codexkey you can create a separate key for the bot, limit its purpose and compare several models on one set of dialogs.
const baseURL = process.env.CODEXKEY_BASE_URL ?? "https://api.codexkey.online";
const apiKey = process.env.CODEXKEY_API_KEY;
if (!apiKey) {
throw new Error("CODEXKEY_API_KEY is missing");
}
const response = await fetch(`${baseURL}/v1/messages`, {
method: "POST",
headers: {
authorization: `Bearer ${apiKey}`,
"anthropic-version": "2023-06-01",
"content-type": "application/json",
"x-request-id": requestId,
},
body: JSON.stringify({
model: "claude-sonnet-5",
max_tokens: 700,
system: SUPPORT_POLICY,
messages: [{ role: "user", content: ticketText }],
}),
});
if (!response.ok) {
throw new Error(`model request failed: ${response.status}`);
}
Log the request ID, model ID, elapsed time, response status, retry count and the router's decision. Mask message text and personal fields or leave them out, especially payment and identity data. More routing examples sit in the Telegram bot provider checklist and the Claude support chatbot guide. Reaching the Claude API from Russia has its own guide.
Human handoff and tests
Define escalation before launch. Payment disputes, identity changes, legal threats, unclear policy, repeated failed answers and a direct request for a person go to an agent. The bot says a person is reviewing the case and shows a reference ID. The agent gets the original message, the policy passages, the draft answer and the reason, and can edit the draft before it reaches Telegram. The model prepares context. Your support system owns the final send.
Keep fixtures for a normal FAQ, an unknown question, an incomplete account request, a prompt injection, a rate limit, a provider timeout and a handoff, and assert both the model request and the Telegram message. Add per-chat concurrency limits, a timeout on every provider call and a bounded retry. Never retry a tool that changes account state without an idempotency key.
FAQ
Which model should I start with?
One fast candidate, such as claude-sonnet-5 or gpt-6-sol, on a closed sample of tickets. Add a flagship once you know where the current model fails.
Can the model change an order or an account?
Only through a server-side tool with permissions, validation, an audit record and approval for sensitive actions. Model output is not authorization.
What goes into the logs?
Request ID, model ID, time, result code, request size and the router's decision. Message text and personal fields are masked or left out.
Can one provider run a Telegram support bot?
It simplifies routing. Keep a tested second route or a human path for provider errors, with the same policy and output format.
Where should the API key live?
In a server environment variable or a secret manager, never in a message, a browser bundle, a mobile app or a repository.
How do I check current model availability?
Read the models documentation and the live catalog right before a release. Keep unknown IDs out of production configuration.