# Channels quickstart

> Five minutes: register your Telegram bot as a channel app, mint a connect link, and talk to your agent in the chat — everything under your bot's identity.

## 1. Bring a bot token

Create a bot with Telegram's **@BotFather** (`/newbot`) and copy its token. You'll also want an AgentSky session to talk to — `sky launch` gives you one, or use any session id from `GET /api/v1/sessions`.

## 2. Register the channel app

```bash
curl -s -X POST https://agentsky.dev/api/v1/channels/apps \
  -H "Authorization: Bearer $AST_TOKEN" -H 'content-type: application/json' \
  -d '{"platform": "telegram", "label": "My bot", "credentials": {"bot_token": "123456:ABC..."}}'
# -> { "id": "app_...", "credential_keys": ["bot_token", "bot_username", "webhook_secret"], ... }
```

Registration proves the token with Telegram and points your bot's webhook at a per-app ingress automatically. Credentials are encrypted at rest and never returned — reads list key names only.

## 3. Connect a chat

```bash
curl -s -X POST https://agentsky.dev/api/v1/channels/connections \
  -H "Authorization: Bearer $AST_TOKEN" -H 'content-type: application/json' \
  -d '{"platform": "telegram", "app": "app_...", "destination": {"session": "sess-your-session-id"}}'
# -> { "id": "...", "status": "PENDING", "connect": { "url": "https://t.me/your_bot?start=..." } }
```

Open the URL and tap **Start**. The chat claims the link (links expire after 15 minutes), the connection flips `CONNECTED`, your session becomes its default binding, and the bot greets the user. A `channel.connected` event lands on your webhook endpoints with your `metadata` echoed.

## 4. Talk

Message the bot — the text becomes an agent turn and the reply lands back in the chat, rendered from markdown. The working marker rides the message (👀 while working on Telegram, resolved when the agent finishes).

```bash
# proactive: post into the thread yourself
curl -s -X POST "https://agentsky.dev/api/v1/channels/threads/telegram:app_...:12345/messages" \
  -H "Authorization: Bearer $AST_TOKEN" -H 'content-type: application/json' \
  -d '{"parts": [{"type": "markdown", "text": "nightly report is **ready**"}]}'
```

## No agent? Route to your own code instead

Skip `destination` and bind the connection to a webhook endpoint: inbound arrives as signed `message.received` events and you answer through the threads API — no AgentSky session involved. See [Routing](/docs/channels/routing.md) and [Webhooks](/docs/channels/webhooks.md).
