You need a running Chowder instance. If you don’t have one yet, follow Your First Instance to get set up.
Set up your environment
Open Telegram and search for @BotFather — it’s Telegram’s official bot for creating bots (very meta).
/newbotbot (e.g., my_chowder_agent_bot)7123456789:AAF1k2j3h4g5f6d7s8a9...curl -X POST https://api.chowder.dev/v1/instances/$INSTANCE_ID/channels/telegram/connect \
-H "Authorization: Bearer $CHOWDER_KEY" \
-H "Content-Type: application/json" \
-d "{
\"config\": {
\"token\": \"$BOT_TOKEN\"
}
}"
{
"channel": "telegram",
"status": "connected",
"qr_data": null,
"qr_image_base64": null,
"message": null
}
openclaw.json config under channels.telegramenabled: true and dmPolicy: "pairing" (more on that next)This prevents random people from racking up your model costs. The first person to message gets a code, and you decide whether to let them in.
The pairing code is shown to the user directly in Telegram. You need to get it from them (or see it in the logs) and then approve it via the API.
curl -X POST https://api.chowder.dev/v1/instances/$INSTANCE_ID/channels/telegram/pair \
-H "Authorization: Bearer $CHOWDER_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "abc123"
}'
{
"channel": "telegram",
"code": "abc123",
"status": "approved",
"output": "Pairing approved for user 123456789."
}
curl https://api.chowder.dev/v1/instances/$INSTANCE_ID/channels/telegram/status \
-H "Authorization: Bearer $CHOWDER_KEY"
curl https://api.chowder.dev/v1/instances/$INSTANCE_ID/channels \
-H "Authorization: Bearer $CHOWDER_KEY"
[
{
"channel": "telegram",
"connection_type": "token",
"enabled": true
},
{
"channel": "discord",
"connection_type": "token",
"enabled": false
},
{
"channel": "whatsapp",
"connection_type": "interactive",
"enabled": false
}
]
curl -X POST https://api.chowder.dev/v1/instances/$INSTANCE_ID/channels/telegram/disconnect \
-H "Authorization: Bearer $CHOWDER_KEY"
How it works under the hood
When you call the connect endpoint, Chowder does the following on your instance’s sandbox:- Reads the
openclaw.jsonconfig file - Writes the bot token to
channels.telegram.botToken - Enables the channel:
channels.telegram.enabled = true - Sets the DM policy:
channels.telegram.dmPolicy = "pairing" - Restarts the gateway process so it picks up the new config
Other channels
Telegram is a “token-based” channel — you give it a token, it connects. Chowder supports a bunch of these:- Token-based
- Interactive
These work the same way as Telegram — pass credentials via the connect endpoint:
| Channel | Required fields |
|---|---|
| Telegram | token (bot token from BotFather) |
| Discord | token (bot token) |
| Slack | bot_token + app_token (for Socket Mode) |
| Signal | account (E.164 phone number) |
| Matrix | homeserver + user_id + access_token |
| MS Teams | app_id + app_password + tenant_id |
| Mattermost | bot_token + base_url |
| LINE | channel_access_token + channel_secret |
| Google Chat | audience_type + audience |