FLOW_MESSAGING_KEY holds your live key (fk_live_...).
curl
Checklist
1
Get a live key
Sign in to the dashboard with GitHub, switch to Live, and make an
fk_live_... key on the Keys page (test keys take one call, see Keys and sign-in). Keep it on your server only, in its own variable (for example FLOW_MESSAGING_LIVE_KEY) so it does not replace your test key. Live Telegram with your own bot is self-serve; iMessage lines are arranged with the Flow team.2
Get a dedicated sender
Telegram:
POST /v1/senders with your bot’s token; it is active at once. iMessage: the Flow team connects a line to your app, and it then appears in GET /v1/senders with your live key (POST /v1/senders with "channel": "imessage" answers 501 not_implemented).3
Register your webhook with the live key
Webhook endpoints belong to one mode.
POST /v1/webhook_endpoints again with the live key and store the new whsec_... secret.4
Switch the key
Set
FLOW_MESSAGING_KEY to the live key and deploy. Watch message.failed and sender.status_changed for the first days.WhatsApp: coming
WhatsApp is not available yet: Flow is waiting on Meta’s approval, andPOST /v1/senders with "channel": "whatsapp" answers 501 not_implemented. When it ships:
- Numbers: Flow buys and hosts a dedicated number for you.
- Verify your business: WhatsApp requires the business behind a number to be verified through Meta; the Flow team will send you the link.
- Quality and tiers: the sender shows WhatsApp’s
quality_rating(green,yellow,red) and its messaging tier inlimits.whatsapp_tier. Replies to people who wrote first are not limited by the tier. - Fees: WhatsApp’s own per-message fees (charged by Meta) are passed through. See Pricing.
WhatsApp templates
A template is a message WhatsApp approved in advance. On WhatsApp you need one to message someone first, or to write more than 24 hours after their last message. Templates need a WhatsApp number, so this is how it will work once WhatsApp ships:curl
- Names use lowercase letters, digits and underscores. A name and language pair is unique per sender.
categoryisutility(updates about something the person asked for),marketingorauthentication; it sets WhatsApp’s fee.- A new template is
pending. You receivetemplate.status_changedwhen WhatsApp approves, rejects (withrejection_reason) or pauses it. - Send it as
templatecontent with values for its placeholders:
iMessage: a line from the Flow team
- Get one: ask the Flow team. They connect a dedicated line to your app; it is listed in
GET /v1/senders?channel=imessagewith your live key. - Replies only: the person always writes first. Starting a conversation with a new contact is refused with
403 permission. - Get people to write: the sender’s
address.linkis the line’s opt-in link (when it has one): it opens Messages with the line and a prefilled text. Publish it on your site, receipts or QR codes. See Build an iMessage agent.
Telegram: your own bot
Create a bot with @BotFather and send its token:POST /v1/senders with channel: "telegram" and telegram_bot_token. It is connected and active at once. See Build a Telegram agent.
- New token: after revoking a token in @BotFather, send the new one the same way. The bot stays the same sender; one Telegram rejected meanwhile is
flaggeduntil you do. Messages queued while it is flagged wait at most 72 hours, then fail withoutside_window(channel_codequeued_too_long). - Disconnect:
DELETE /v1/senders/{sender_id}removes the bot’s webhook and token and retires the sender. - One app per bot: connecting a bot to another app moves it there and retires the old sender.
Before you launch
- Handle
outside_window,new_contact_limitandsender_throttled(see Errors). - Deduplicate webhook deliveries on the event
id, and use event IDs as idempotency keys. - Subscribe your webhook only to the event types you use.
- Message content and media are kept for your plan’s retention period (30 days by default); store anything you need longer yourself.