API429 / Telegram Bot

Telegram Bot with API429: private polling, durable state and offline check

Telegram bots connect to API429 through your own application code, combining the Telegram Bot API with API429 Chat Completions. Download both shared files to run the zero-network synthetic cycle first, then review the strict operator guards before executing a single live pass.

Configuration is based on the application’s public documentation and the API429 contract. Native client execution, installation imports and agent workflows have not been verified here. Start with a short non-sensitive request and inspect the response in your installed version.

Connection settings

Protocol
OpenAI Chat Completions
Connection mode
Telegram: dedicated private polling loop
Base URL
https://gateway.api429.com/v1
Exact model ID to check
gemini-3.8-flash

Check access for your key with GET /v1/models. A public model card does not guarantee availability in your application. Store the key in the application’s secure credential store or the current session environment. Keep secret values out of command arguments and shared project files.

Download both shared files and run the offline synthetic cycle first

This reference implementation requires Python 3.10 or newer on a POSIX system such as macOS or Linux and uses only the Python standard library. Download both shared files—api429-telegram-private-bot.py and api429-telegram-update-synthetic.json—into the same directory while keeping their exact filenames. Run python3 -B api429-telegram-private-bot.py from that directory; if the companion JSON fixture is missing or corrupted, the script halts immediately. The -B flag simply suppresses Python bytecode cache files and does not enable network access.

Without operator flags, the script runs an isolated mock transport with temporary local state and prints the exact line OFFLINE synthetic cycle: sent; network requests: 0. All user, chat and bot IDs, catalog records and service responses in that run are synthetic. Passing this check confirms only that the local state machine and parser ran cleanly on your machine; it requires no API keys, sends zero network packets and does not verify live Telegram delivery or paid model inference.

Separate the two contracts and prepare a dedicated operator bot

Telegram does not offer a built-in OpenAI Base URL field inside BotFather or the client app. Instead, your Python process communicates with two distinct HTTPS services: the Telegram Bot API for bot updates and messages, and https://gateway.api429.com/v1 for OpenAI-compatible POST /v1/chat/completions using gemini-3.8-flash. Verify that your API429 key can access gemini-3.8-flash via GET /v1/models before attempting a live run.

Live operator mode (--execute-once) is designed solely for a dedicated bot owned by the operator. Before running it, confirm that no other poller or worker is calling getUpdates for that bot on the same host, another server or an automation platform, and acknowledge that requirement with --dedicated-bot-no-other-poller. The script's POSIX file lock protects only the local --state-dir on a single filesystem and cannot coordinate across machines.

Inject both secrets securely and pass explicit allowlist flags

Supply TELEGRAM_BOT_TOKEN and API429_API_KEY through a protected environment mechanism in your operator shell—such as a secret manager injection, hidden read -s input in Bash or getpass—never as command-line arguments, hardcoded strings, shell history entries or committed files. Export API429_MODEL=gemini-3.8-flash so the script validates and requests the intended Google model ID.

Pass your verified numeric identifiers explicitly on the command line: --expected-bot-id, --allowed-user-id and --allowed-chat-id. The numbers 123 and 456 in the command example are synthetic placeholders that you must replace with your own bot ID and private user/chat ID. Point --state-dir to a private absolute POSIX directory such as /private/bot-state that persists across single-pass invocations.

Inspect the single-pass checks and private message filter

When invoked with --execute-once, the script runs a single bounded cycle rather than an infinite daemon loop. First, it calls getMe and verifies that the bot ID matches --expected-bot-id. Next, it calls getWebhookInfo and requires an empty webhook URL: if a webhook is active or ambiguous, the script halts without calling deleteWebhook or mutating your bot configuration. Only after checking the model catalog does it call getUpdates with limit=1, timeout=0 and allowed_updates=["message"].

The handler accepts only a recent plain-text message in a private chat where both the sender and chat match --allowed-user-id and --allowed-chat-id, the sender is not a bot, the message age is at most 600 seconds and the text length is at most 4096 UTF-16 code units. Groups, channels, edits, forwards, business messages and unrecognized fields are skipped or halt the pass. For an accepted message, the script makes at most one POST /v1/chat/completions request (max_tokens=256, stream=false) and at most one plain-text sendMessage call.

Manage durable state transitions, uncertain outcomes and 24-hour offsets

To prevent duplicate paid requests or duplicate Telegram replies after a crash, the script writes durable state before each network side effect: reserved before calling API429 Chat Completions, send_pending before calling Telegram sendMessage, and terminal only after confirmed completion. If a run crashes or receives an ambiguous network outcome, the state remains reserved or send_pending indefinitely and blocks future runs. Never delete --state-dir to force a blind retry; reconcile the outcome in API429 and Telegram manually under this at-most-once attempt policy.

A positive getUpdates offset (previous update_id plus one) is sent only when a confirmed terminal record is younger than 24 hours; older terminal offsets are omitted because Telegram stores updates for at most 24 hours and may assign a new update_id after a week of inactivity, while reserved and send_pending states never expire. If you prefer a visual workflow builder instead of maintaining a POSIX state directory, compare the manual HTTP guides for n8n (/en/integrations/n8n) and Make (/en/integrations/make).

Settings and examples

Both shared files in one directory: default offline synthetic run

python3 -B api429-telegram-private-bot.py
# OFFLINE synthetic cycle: sent; network requests: 0.

Operator-only single pass: may incur usage and send one message; replace synthetic IDs

# TELEGRAM_BOT_TOKEN and API429_API_KEY are already injected securely into the environment.
export API429_MODEL=gemini-3.8-flash
python3 -B api429-telegram-private-bot.py --execute-once --expected-bot-id 123 --allowed-user-id 456 --allowed-chat-id 456 --state-dir /private/bot-state --dedicated-bot-no-other-poller

Download the Telegram bot Python example · Download the synthetic update (JSON). Save both files in the same folder. Running by default executes only the offline cycle; the real operator polling mode is described above.

Usage and next steps

Hypothetical hourly workload: 30 requests to gemini-3.8-flash, each with 5,000 ordinary input and 512 output tokens, costs approximately $0.05 at current API429 rates. Cache, tools, retries, application subscriptions and other fees are excluded. Catalog date: .

Actual usage depends on request count, context length and response size. Check your API429 account for actual charges.

API reference · API429 documentation · Help and diagnostics

Payment and a $10 test

  • Russian bank card. Top up your balance in the account.
  • Invoice for companies. Bank transfer with closing documents.
  • USDT and TON. Top up in crypto.

$10 test credit. Subscribe to our Telegram channel through the bot and get $10 on your balance for the first requests. Get $10 in the bot

Frequently asked questions

Why does the default run print sent without sending a Telegram message?

Running python3 -B api429-telegram-private-bot.py without --execute-once executes the offline synthetic fixture over a mock transport, printing OFFLINE synthetic cycle: sent; network requests: 0. without keys or network calls.

Will the script delete an existing webhook or coordinate with another poller?

No. If getWebhookInfo returns a non-empty URL, the script stops without calling deleteWebhook. You must also ensure no other poller uses the bot and pass --dedicated-bot-no-other-poller.

What should I do if the state directory stops in reserved or send_pending?

Do not delete the state directory or re-run automatically, because the paid model call or Telegram message may already have succeeded. Inspect API429 usage and the Telegram chat manually before resolving.

Why does the positive update offset expire after 24 hours while max_tokens is 256?

Telegram keeps unconfirmed updates for up to 24 hours, so stale terminal offsets are dropped while uncertain states stay blocking forever. Setting max_tokens=256 bounds one reply, not total input tokens or account spend.

Sources

The application documentation defines its interface and limitations; API429 documentation defines addresses, authentication and client methods. Connection configuration checked: .

Telegram