Channels compared
Every channel a Keiki agent can run on, what it can do there, how long it takes to go live, and its limits.
One agent runs on any mix of these channels. Tools, memory, steering and billing sit above the channel layer, so one config serves them all. Add a channel from Channels → Add channel or an agent's Channels tab.
At a glance
| Channel | You connect | Ready in | Status |
|---|---|---|---|
| iMessage, dedicated line | A line bought in Keiki, or imported from your provider account | Right away to a few days, by line type | Live |
| iMessage, shared number | Nothing: the agent gets a join code | Right away | Live |
| A number through WhatsApp's guided signup, your Kapso account, or your own Meta app | About 5 minutes | Live | |
| Telegram | A bot token from @BotFather | Right away | Live |
| Slack | A Slack app created from Keiki's manifest | A few minutes | Live |
| Microsoft Teams | An Azure Bot registration and the app package | Minutes to days, by your Microsoft 365 admin | Live |
| An AgentMail inbox, US or EU region | Right away; a custom domain waits for DNS | Live | |
| X | An X account, through Log in with X | Right away | Live |
| Phone calls | A US local number bought in Keiki | Right away | Live |
| Apple Messages for Business | A channel Keiki assigns | After review | Request access |
| SMS/RCS | A request with your purpose and volume | After review | Early access |
iMessage reaches Android users too: the line's provider falls back to SMS/RCS on the same number (what that supports).
Everything except a bought iMessage line needs an active plan. Without one, connecting
answers plan_required.
What each channel supports
The shared tools are reply, react, update_message, delete_message and send_file.
A channel without a feature answers unsupported before anything is sent.
| Capability | iMessage | Slack | Telegram | Teams | SMS fallback | ||
|---|---|---|---|---|---|---|---|
| Reply | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Reply to a specific message | Yes | Yes | No | Yes | No | No | No |
| React | Yes | Yes | Yes | Yes | No | No | No |
| Edit a sent message | Yes | No | Yes | Yes | No | Yes | No |
| Delete a sent message | Yes | No | Yes | Yes | No | Yes | No |
| Receive files | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
| Send files | Yes | Yes | Yes | Yes | Yes | No | Yes |
| Send a file as a reply | No | Yes | No | Yes | No | No | No |
| Voice notes | Yes | Yes | No | Yes | No | No | No |
| Message effects | Yes | No | No | No | No | No | No |
SMS fallback is an iMessage contact on Android, or with iMessage turned off. The line's provider delivers to them over SMS/RCS instead, so the agent gets plain text and files only.
iMessage line types
The iMessage column above is an Instant line.
| Capability | Instant | Standard | On request |
|---|---|---|---|
| Edit a sent message | Yes | No | Yes |
| Delete a sent message | Yes | No | No |
| Send files | Yes | Yes | No |
| Voice notes | Yes | No | No |
| Polls | Yes | Yes | No |
| Contact cards | Yes | Yes | Yes |
| iMessage Apps cards | Yes | No | No |
Edit and delete need the contact on iMessage, not SMS, within Apple's time limits.
Beyond the shared tools
| Channel | Adds | Guide |
|---|---|---|
| iMessage | Tapbacks, threaded replies, effects; group chats on dedicated photon or blooio lines with Group chats enabled; linq lines ignore groups | iMessage Apps, Group chats |
Native cards from one send_card spec | Native cards | |
| Slack | Threaded answers, approval buttons, human handoff in a thread, native cards | Slack agents, customer workspaces |
| Microsoft Teams | Native cards | Native cards |
| Telegram | With Group chats enabled, answers only when addressed unless you change replyMode; native cards as inline keyboards, with private (ephemeral) replies to a button press in groups; HTML widgets in private chats with Dynamic UI on; card numbers masked on arrival | Group chats, Native cards, Telegram widgets |
| Replies in the same thread, with attachments | ||
| Apple Messages for Business | Text and media, a choice picker (ask_question) and a time picker (offer_times) | Apple Messages for Business |
| X | Text direct messages and public replies to posts that mention the account | |
| Phone calls | Inbound and outbound calls; voice, tone and greeting per line; 13 languages |
Provisioning
iMessage lines
| Line | Ready in | Notes |
|---|---|---|
| Instant | Right away | Bought from Channels → Buy line |
| Standard | A few minutes | Bought from Channels → Buy line |
| On request | When the team fills the request by hand | Not charged at request time; you get an email when it's ready |
| Imported | Once the account's credentials check out | From your own iMessage provider account |
| Shared number | Right away | Contacts text a join code such as K-7QF2MD. See Shared iMessage number |
Everything else
| Channel | Steps |
|---|---|
| Log in with Facebook → pick a business → verify the number. It keeps working in the WhatsApp Business app | |
| WhatsApp, your own Meta app | Connect it → add the callback URL and verify token in Meta's webhook settings (Meta has no API for this step) |
| Telegram | Paste the @BotFather token. Keiki sets the webhook |
| Slack | Create the app from Keiki's manifest → install it. Customer workspaces join through a signed install link |
| Microsoft Teams | Register the bot in Azure → connect it in Keiki → install the app package. A tenant-wide upload may need a Microsoft 365 admin; the tenant appears after its first message |
| Create the inbox. On your own domain, add the DNS records shown; AgentMail verifies them a few minutes after DNS propagates | |
| X | Log in with X |
| Phone calls | Channels → Phone calls → Buy line → pick an area code or state, or let Keiki choose. An agent can hold several lines |
| Apple Messages for Business | Request access with your purpose and monthly volume → the team assigns a channel |
| SMS/RCS | Request access with your purpose and monthly volume |
Limits
| Channel | Files | Message size | Daily volume | Other |
|---|---|---|---|---|
| iMessage | 100 MB | 7,000 sent and 50 new conversations per line per UTC day, pooled across your lines | Past a cap: daily_line_volume_reached. Plan for 5,000 a day (best practices) | |
| iMessage, Standard line | Same as iMessage | After several unanswered messages: recipient_reply_required | ||
| iMessage, shared number | The caps count every organization on the number | Replies only to contacts who texted its code; no contact card | ||
| 100 MB; Meta caps images at 5 MB, audio and video at 16 MB | Voice notes in OGG/Opus. Outside Meta's service window: recipient_reply_required (Meta error 131047) | |||
| Telegram | 50 MB | Captions over 1,024 characters go as their own message; 10 files per album | Deletes in a private chat only within 48 hours | |
| Slack | 1 GB | Split at about 3,800 characters | Edits and deletes only in the current thread | |
| Microsoft Teams | Receive only | Split at 20,000 characters | ||
| 25 MB, sent or received | The first 10 inbound attachments are described to the agent; the rest are listed | |||
| Apple Messages for Business | 100 MB | Choice picker: 5 options, 24-character titles. Time picker: 10 slots | Customer-initiated only; no reactions or contact cards | |
| X | Text only | A token X rejects shows Reconnect | ||
| Phone calls | US local numbers; each minute spends platform credit |
recipient_reply_required also applies when an inbound-only line tries to contact someone
who has not messaged it first. It is not retryable, and a platform notice doesn't clear it: only a
real message from the contact does. To bring the contact back from a page your app hosts,
use the return link.