> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flow.engineer/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a sender

> Choose 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 the Flow team connects to your app (Dedicated plan); group chats, and on request SMS and RCS fallback, call forwarding and writing first |
| WhatsApp | 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 |

```bash theme={null}
curl https://api.flow.engineer/v0/senders \
  -H "Authorization: Bearer $FLOW_MESSAGING_KEY"
```

```json theme={null}
{
  "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": "Hi 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`, set by the Flow team: `fallback` (messages to someone not on iMessage go by SMS or RCS from the same number; included on the shared line, an add-on on a dedicated line), `call_forwarding.phone` (dedicated lines only: where phone calls to the number are forwarded) and `can_initiate` (the line may write first; available on request, dedicated lines only). See [iMessage](https://docs.flow.engineer/unified-messaging-api/guides/imessage-agent.md).

## 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: ask the Flow team. See [Going live](https://docs.flow.engineer/unified-messaging-api/guides/going-live.md) |

A third kind, `simulated`, exists only in test mode: your app's stand-in for a channel,
used by [simulated contacts](https://docs.flow.engineer/unified-messaging-api/concepts/test-and-live-mode.md#simulated-contacts-test-without-a-phone).
It never touches a network, and `GET /v0/senders` lists it only with `kind=simulated`.

## 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 `Hi 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_code` in `GET /v0/app` (the bare code, for example `wild-otter-04508705`); each shared sender shows the whole message a person sends as `join_code` (`Hi Sandbox app (ref wild-otter-04508705)`): `Hi`, your app's name and the code in brackets. Show it as it is. Any message of up to 160 characters that ends with `(ref <code>)` joins; `join <code>` does not.
* A join starts a conversation and sends you `conversation.started` with `via: "sandbox_join"`, then the join itself as the person's first `message.received`, so your agent can answer at once: the text before `(ref <code>)` (`Hi Sandbox app`, or `Hi` when nothing is left), or `/start` when 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

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](https://docs.flow.engineer/unified-messaging-api/concepts/send-gate.md).

## Related

* [Conversations and channels](https://docs.flow.engineer/unified-messaging-api/concepts/conversations.md)
* [Test and live mode](https://docs.flow.engineer/unified-messaging-api/concepts/test-and-live-mode.md)
* [Going live](https://docs.flow.engineer/unified-messaging-api/guides/going-live.md)
* API: [List senders](https://docs.flow.engineer/api-reference/senders/list-senders.md), [Request a dedicated sender](https://docs.flow.engineer/api-reference/senders/request-a-dedicated-sender.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.