Skip to main content

Troubleshooting: Telegram channel errors

Telegram fails at two distinct layers: when you connect a bot to your organization, or when you send through an already-connected bot. The classified error codes in the error-codes reference split the same way — the first two below are connect-time failures, the other two are send-time failures. Work the layer that matches the code on the page before reconnecting anything. This page covers the channel-level error codes. For send-rejected causes on a connected bot (INVALID_RECIPIENT, MISSING_REQUIRED_FIELD, RATE_LIMIT_EXCEEDED, MESSAGE_SEND_FAILED), see the Telegram channel page.

Symptom map

Read the calling surface first: a connect call (POST /api/v1/telegram/connect-bot) fails with one of the two connect codes; a send call (POST /api/v1/messages/telegram or the sandbox POST /api/v1/telegram/test/send) fails with one of the two send codes. The same dashboard badge reads either way.

Connect-flow errors

1. TELEGRAM_INVALID_BOT_TOKEN — the token did not pass validation

Orbit validates a pasted token in two stages before persisting it: a format check (<digits>:<secret> — a bot id, a colon, the BotFather secret), then a live getMe round-trip against the Telegram Bot API. Either stage failing rejects the paste with this code. Trailing whitespace from a copy-paste is trimmed automatically; a pasted BotFather URL, a partial token, or a revoked token fails. Resolution: confirm the token works directly against Telegram before you paste it again:
A healthy token returns {"ok": true, "result": {"id": 7654321098, "is_bot": true, "username": "…"}}. If that call returns 401 Unauthorized, the token is dead — issue a fresh one with /revoke in @BotFather and paste the new value. If getMe succeeds but the Orbit paste still fails, you are pasting more (or less) than the token — paste exactly the digits:characters string BotFather issued.

2. TELEGRAM_BOT_ALREADY_CONNECTED — the bot is already claimed (HTTP 409)

A connect attempt fails closed when the bot’s bot_id (the numeric prefix before the colon) is already registered on an Orbit organization. Two cases:
  • Your own organization already has a bot connected. One bot per organization — the new connect is refused until the existing bot is disconnected. This is also the path to rotate a token: you must disconnect before you reconnect.
  • Another Orbit organization holds the claim. Someone (a teammate’s other org, or a leaked token claimed by a third party) connected this bot first. Follow the ownership dispute recovery paths on the channel page.
Resolution: for your own org, open Settings → Channels → Telegram in the dashboard, open the bot card, and choose Disconnect. Then connect again with Add bot — the same two operations are available over the API as POST /api/v1/telegram/disconnect-bot and POST /api/v1/telegram/connect-bot. Conversation history survives the rotation because Orbit keys it by bot_id, not by the token. For another org’s claim, disconnect from that org (or work the ownership-dispute path) before retrying.

Send-path errors

3. TELEGRAM_CHANNEL_NOT_CONNECTED — no active bot on the org (HTTP 409)

A send was attempted — a production POST /api/v1/messages/telegram call, or the sandbox POST /api/v1/telegram/test/send — while the organization has no active bot row. In test mode this fires when no chat has completed the sandbox verification yet; in production mode it fires after a disconnect, or before the first ever connect. Resolution: read GET /api/v1/telegram/channel-state. If mode is not_connected, connect a bot (POST /api/v1/telegram/connect-bot, or the dashboard Settings → Channels → Telegram → Add bot) before sending. If you expect the sandbox (test) path, POST /api/v1/telegram/test/start-verify and complete the /start deep-link first. Do not gate production sends on the sandbox verification — the two modes are independent.

4. TELEGRAM_PROVIDER_ERROR — Telegram returned a non-2xx or a network failure

The call to Telegram’s Bot API (getMe, setWebhook, or sendMessage) returned {ok: false, description: "…"} over a non-2xx status, or the network hop itself failed. The description Telegram returns is the root cause — a revoked token (401), chat not found, or Telegram-side outage. A plain network failure means the request never reached Telegram and is usually transient. Resolution: probe the stored token with the same getMe cURL shown above. If Telegram answers 401, rotate the token in BotFather and disconnect/reconnect from Settings → Channels → Telegram with the new value. If getMe succeeds, read the error envelope’s description — Telegram’s own wording tells you which call failed and why. For transient network failures, retry the send; Orbit already honors Telegram’s retry_after on flood-control 429s. A provider error that persists across valid tokens and retried sends belongs in a support ticket (below).

Reconnect decision table

Disconnect/reconnect from Settings → Channels → Telegram (dashboard Disconnect then Add bot, or the API disconnect-bot / connect-bot pair). A fresh token reconnect preserves the bot’s conversation history — Orbit keys history by bot_id, not by token.

What not to do

  • Do not retry a connect on an invalid token. TELEGRAM_INVALID_BOT_TOKEN is deterministic — paste-validation fails the same way every time. Rotate the token in BotFather, then reconnect.
  • Do not force the second-org claim from your dashboard. A TELEGRAM_BOT_ALREADY_CONNECTED 409 owned by another organization resolves through the ownership dispute path only; reconnecting loops the same 409.
  • Do not treat a provider error as a connection problem. Disconnect and reconnect the bot only after getMe proves the token is dead; otherwise you are solving the payload or the transient network with a credentials reset.

When to escalate

Open a support ticket when one of these holds:
  • getMe succeeds against Telegram directly, but connect still returns TELEGRAM_INVALID_BOT_TOKEN and the pasted value is exactly the issued token.
  • TELEGRAM_PROVIDER_ERROR persists across freshly rotated tokens and retried sends, with a description Telegram does not document.
  • An ownership dispute where the claim-releasing steps in Ownership disputes have been followed and the 409 remains.
Include all three so support can pull the Telegram provider trace without a back-and-forth:
  • Your tenant ID (dashboard under Settings → Organization, or organizationId on GET /api/v1/me).
  • The bot’s @username and the numeric bot id (the digits before the colon in any token you have held).
  • One request ID (from the request_id envelope field) of a failing, non-redacted connect or send call — plus the classified error code it returned.

See also