Channels

Channels overview

One row per catalog adapter. Always pass via="hosted" or via="self-host". Self-host needs a local adapter and that channel’s secrets — not a Caspian API key. Hosted-only names the gateway speaks (Bluesky, …) are not rows — inbound arrives as a gateway event.

The catalog

Channel Inbound Bot token Self-host loop
Telegram webhook, poll always (BotFather) handle or poll
Slack webhook, socket self-host listen("slack")
Discord socket only self-host listen("discord")
Email webhook self-host handle("email", …)
WhatsApp webhook self-host handle + Meta verify GET
Messenger webhook self-host handle + Meta verify GET
SMS webhook self-host handle (Twilio form)
Voice webhook self-host handle + TwiML response
iMessage webhook self-host handle (relay HMAC)
X webhook self-host handle + CRC GET
Linear webhook self-host handle

Capabilities (what thread.* can do)

Derived from caspian.catalog. Adapters degrade where they must (SMS has no buttons; Telegram send_blocks is text + keyboard).

buttonseditreacttypingmediavoice
Telegram
Slack
Discord
Email
WhatsApp
Messenger
SMS
Voice
iMessage
X
Linear

Self-host add() currently requires bot_token for every catalog row. Channels that do not have a BotFather-style token pass bot_token="local" so paperwork succeeds; the real secrets are the ones in each example (access_token, account_sid, …).