Skip to main content
Connect your own WhatsApp number with a live key, receive messages and deliver your agent’s answer through the Unified API. Use buttons in the reply window and approved templates after it.
Connect a number in your WhatsApp Business Account with POST /v0/senders or the dashboard’s Senders page. The shared WhatsApp sandbox is not open; test on Telegram first with the same handler.
TypeScript
On serverless platforms that stop work when the response is sent, run the reply with your platform’s background helper (for example after() in Next.js or waitUntil()), or answer in the webhook response itself as shown below.

1. Build it on Telegram today

There is no WhatsApp sandbox yet. Run the same code on the Telegram sandbox bot:
  1. Get a test key, with no account: curl -X POST https://api.flow.engineer/v0/sandbox/keys (or npx @flow-engineer/messaging init). Set its key as FLOW_MESSAGING_KEY. See Keys and sign-in.
  2. Join the Telegram sandbox from your phone with the bot’s address.link (see Build a Telegram agent).
  3. Register your webhook, or on your laptop read events from the live stream (GET /v0/stream, see Local development), and send a message.
When the WhatsApp sandbox opens, the sandbox allowance will cover it.

2. Answer fast: reply in the webhook response

For short answers, skip the extra API call and return the reply from the webhook handler:
TypeScript
HTTP response body
Answer within 10 seconds; for anything slower, answer 200 {} at once and send with the kinds’ endpoints, such as POST /v0/conversations/{conversation_id}/basic.

3. Voice notes

WhatsApp users send a lot of voice notes. Each one arrives as a voice message with the audio file (url, file_id):
Flow does not transcribe voice notes yet, so fetch the audio and transcribe it yourself if your agent needs the words. To send a voice note back, use POST /v0/conversations/{conversation_id}/voice with an audio url or file_id.

4. Buttons and lists

WhatsApp shows up to 3 reply buttons (buttons). For 4 to 10 choices, send a list: more than 3 buttons answer 422 unsupported_content with param buttons, and Flow does not turn them into a list for you.
TypeScript
A tap on a button or a list row arrives as message.received with a button_reply message: { "kind": "button_reply", "button_id": "upi", "label": "UPI" }. Labels are at most 20 characters.

5. The 24-hour window and templates

WhatsApp allows free-form messages only within 24 hours of the person’s last message. After that, and to message someone first, you must send an approved template.
  • Every event carries conversation.window_open_until.
  • A free-form send outside the window fails with 409 outside_window.
  • Subscribe to conversation.window_closing to get a warning 1 hour before it closes.
TypeScript
Templates are created on your dedicated WhatsApp number with POST /v0/templates, with a realistic sample for each placeholder (examples), and reviewed by WhatsApp; you receive template.status_changed when one is approved, rejected or paused. See Going live.

6. What WhatsApp supports

7. Going live on WhatsApp

Connect a number in your business’s own WhatsApp Business Account yourself, with POST /v0/senders ("channel": "whatsapp") and a live key, or on the dashboard’s Senders page: see Going live for the steps in Meta Business Manager and the setup to enter in your Meta app. The Flow team can also connect a number for you, either one Flow provides or one in your own account. With your own account, add a payment method in WhatsApp Manager: Meta bills its fees to your business directly. On a number Flow provides, Meta’s per-message fees are passed through (see Pricing). Once the number is connected it appears in GET /v0/senders with your live key, and your agent’s code stays the same.
WhatsApp’s business policy does not allow general-purpose AI assistants. Your agent must serve your business’s own customers (support, orders, bookings, updates). Agents that only reply to people who wrote first, about your business, are the safe pattern.