Connect a sender
Senders · WhatsApp number for AI agent · iMessage line for AI agent · Telegram bot for AI agent · messaging sandbox · dedicated WhatsApp number APIChoose the bot, number or line your agent sends from.
A sender is the bot, number or line your agent talks from. Use a shared Telegram sender for a sandbox trial, then connect a dedicated sender for real customers.
| Channel | Shared | Dedicated (live key) |
|---|---|---|
| Telegram | Flow’s sandbox bot | Your own bot: connect its token with POST /v0/senders |
| iMessage | Flow’s shared line, test and live keys, once your account has it (the free trial opens it); ignores group chats | A line of your own on the Dedicated plan, bought in the dashboard; Flow reviews the line, then connects it to your app; group chats and call forwarding, SMS and RCS fallback (included on every iMessage line, the shared one too), and as an add-on writing first (Outbound) |
| Not open yet | A number in your business’s own WhatsApp Business Account: connect it with POST /v0/senders, or the Flow team connects one for you |
curl https://api.flow.engineer/v0/senders \ -H "Authorization: Bearer $FLOW_MESSAGING_KEY"{ "data": [ { "id": "snd_01JB8ZC3K5M7P9R1T3V5X7Z9B1", "channel": "telegram", "kind": "shared", "livemode": false, "status": "active", "address": { "username": "FlowSandboxBot", "link": "https://t.me/FlowSandboxBot?start=wild-otter-04508705" }, "join_code": "Join Sandbox app (ref wild-otter-04508705)", "limits": { "new_contacts_per_day": 50, "new_contacts_per_hour": 10 }, "created_at": "2026-11-01T09:00:00Z" } ], "has_more": false}address.link opens a chat with the sender: https://t.me/... for a Telegram bot (and https://wa.me/... for a WhatsApp number). On the Telegram sandbox bot the link carries your join code (https://t.me/<bot>?start=<code>), so opening it and tapping Start joins your app. For an iMessage line it is the line’s opt-in link, which opens Messages with the line and a prefilled text the person sends to start the conversation; it is set only when the line has one configured.
An iMessage sender also has imessage, read-only, which follows the line: fallback (messages to someone not on iMessage go by SMS or RCS from the same number; included on every line, the shared line too), call_forwarding.phone (dedicated lines only, included: where phone calls to the number are forwarded) and can_initiate (the line may write first; the Outbound add-on, dedicated lines only). See iMessage.
Two kinds of sender
Section titled “Two kinds of sender”| Shared | Dedicated | |
|---|---|---|
| Who uses it | Many apps, in test mode (the shared iMessage line in both modes) | Your app only, in live mode |
| Key | fk_test_... (the shared iMessage line also fk_live_...) | fk_live_... |
| Who it can talk to | Only people who sent your app’s join code | Anyone the channel’s rules allow |
| Name people see | Flow’s sandbox name | Your brand |
| How you get it | Already there (the shared iMessage line: with the free trial your first sign-in at flow.engineer starts) | Telegram: POST /v0/senders with your bot’s token. WhatsApp: POST /v0/senders with your number’s IDs, token and app secret. iMessage: buy Dedicated in the dashboard; Flow reviews the line, then sets it up, usually within a day. See Going live |
A third kind, simulated, exists only in test mode: your app’s stand-in for a channel,
used by simulated contacts.
It never touches a network, and GET /v0/senders lists it only with kind=simulated.
The sandbox and join codes
Section titled “The sandbox and join codes”A shared sender serves many apps at once. A person joins your app by sending the sender’s join message, such as Join Sandbox app (ref wild-otter-04508705), to the sandbox sender. On Telegram, opening the sender’s address.link and tapping Start does the same; typing the join message is the fallback when the link can’t be used. From then on their messages reach your app, and your app can message them.
- A join code is two words and eight digits. Your app’s code is
sandbox_join_codeinGET /v0/app(the bare code, for examplewild-otter-04508705); each shared sender shows the whole message a person sends asjoin_code(Join Sandbox app (ref wild-otter-04508705)):Join, your app’s name (my agentwhen it has none; over 60 characters it is cut at a word) and the code in brackets. Show it as it is. Any message of up to 160 characters that ends with(ref <code>)joins, so olderHi Sandbox app (ref ...)messages from links already shared still work;join <code>does not. - A join starts a conversation and sends you
conversation.startedwithvia: "sandbox_join", then the join itself as the person’s firstmessage.received, so your agent can answer at once: the text before(ref <code>), trimmed (Join Sandbox app, orHiwhen nothing is left), or/startwhen they joined through the Telegram link. - Your test key cannot message anyone who has not joined. That is what keeps the sandbox safe for everyone.
Status and limits
Section titled “Status and limits”Each sender has its own status and budget for starting conversations:
status | Meaning |
|---|---|
pending | Requested; Flow is provisioning it (for senders Flow provisions). |
active | Sending normally. |
warming_up | Active, with a new-contact budget that grows day by day. |
throttled | Slowed after an abuse signal; recovers by itself at throttled_until. Replies still go. |
flagged | Flagged by the channel or by Flow; starting conversations is paused. A Telegram bot whose token Telegram rejected is flagged and holds its queued messages until you send the new token (POST /v0/senders); held messages fail with outside_window (channel_code queued_too_long) after 72 hours. |
banned | It cannot send or receive: the channel banned it, you disconnected it (DELETE /v0/senders/{sender_id}), or its bot or line was connected to another app. |
limits.new_contacts_per_day and limits.new_contacts_per_hour are the sender’s current budget for starting conversations; WhatsApp senders also show quality_rating and limits.whatsapp_tier. Every change arrives as a sender.status_changed event. The rules behind them are on The send gate.
Related
Section titled “Related”Thanks, we read every comment.