WhatsApp runs through the same POST /v1/messages endpoint as everything else. Connect your WhatsApp Business Account once, then send text, media, and WhatsApp’s interactive message types from your numbers.
WhatsApp is in beta and enabled on every account. Send feedback to [email protected].
In this guide
- Connecting: link your WhatsApp Business Account
- The 24-hour window: the one rule that shapes everything else
- Sending: text, media, quote replies, buttons, list menus, link buttons
- Templates: the only way to message someone outside the window
- Receiving: inbound messages, button taps, and what they link back to
- Billing: Meta charges your WABA directly, not your AgentPhone credits
Connecting
Go to WhatsApp in the dashboard and click Connect WhatsApp. That runs Meta’s Embedded Signup in a popup, where you either create a WhatsApp Business Account or pick an existing one, then choose a phone number.
You need a phone number that is not already registered to WhatsApp. If the number you want is on WhatsApp Business today, delete it from that account first, or Meta will refuse it.
Once connected, GET /integrations/whatsapp/status returns your connection and the numbers on it:
The 24-hour window
This is the rule that shapes every WhatsApp integration, and it comes from Meta, not from us.
You can only send a free-form message to someone if they messaged you within the last 24 hours. That window opens on each inbound message and closes 24 hours after the most recent one. Inside it, send whatever you like. Outside it, Meta rejects the send and we return a 422.
The only way to reach someone outside the window is an approved template. There is no workaround, and buying more numbers does not help.
To know where you stand, GET /v1/conversations/{id} reports it:
When the window has closed, canSendMessages is false and sendDisabledReason says so, so you can branch to a template instead of eating a failed send.
Sending
Every send is POST /v1/messages with channel: "whatsapp".
channel: "whatsapp" is only required on numbers that carry both a WhatsApp connection and a regular SMS provider, where we would otherwise not know which transport you meant. Passing it always is harmless and makes the intent obvious.
Text
Media
Pass one public HTTPS URL in media_urls. WhatsApp takes one attachment per message, so a second URL is a 400 rather than a silent drop.
Images, video, audio, documents, and stickers all work. Audio cannot carry a caption, so send the text as its own message.
Quote replies
Set reply_to_message_id to an AgentPhone Message.id and your message renders with that message quoted above it. Useful when the customer sent five things at once and you are answering the third.
The parent must be in the same chat, sent from the same number, and on the WhatsApp channel. Quoting an SMS message from a dual-channel number returns 404, because a WhatsApp message ID means nothing to the cellular network. Meta also refuses to quote anything older than 30 days.
reply_to_message_id cannot be combined with template, buttons, list, or cta.
Reply buttons
Up to 3 buttons, 20 characters each.
Add media_urls and the media becomes a header above the text, in the same bubble as the buttons. Image, video, and document headers all work; audio has no header form and returns 422.
Repeat that call once per item to build a catalog. WhatsApp has no horizontally swipeable carousel outside of approved carousel templates, so a stack of image-header button messages is the closest thing available on a session message.
List menus
Up to 10 rows, 24 characters each. Better than buttons when there are more than three choices.
The full form adds sections and per-row descriptions:
List messages take a text header only. Media on a list send is rejected, because Meta will not render it.
Link buttons
One tappable link on an ordinary message, with no template review.
Reactions
Classic names (love, like, dislike, laugh, emphasize, question) map to emoji, or pass a single emoji directly.
Templates
Templates are pre-approved message bodies. They are the only way to open a conversation or follow up after the 24-hour window has closed.
Create one
Meta reviews it. UTILITY templates usually clear in minutes, MARKETING can take longer, and Meta may recategorize based on the content. Any component containing a variable needs an example or the submission is rejected.
Names must be lowercase letters, digits, and underscores.
Check status
Each template reports a status: APPROVED, PENDING, REJECTED, PAUSED, DISABLED, and a few more. Only APPROVED templates can be sent. A rejection comes with rejected_reason.
Filter with ?status=APPROVED, ?name=, ?category=, or ?language=.
Send one
body is not delivered for a template send, since WhatsApp renders the approved content. We keep it only as a fallback label in your message history.
Templates authored with named variables ({{first_name}} instead of {{1}}) take an object, and the shape has to match how the template was authored or Meta rejects the send:
Pass header_variables for a template whose header has variables of its own.
Template Library
Meta ships a library of pre-written templates. Build from one with library_template_name instead of components:
Delete one
Deleting by name alone removes every language variant under that name, so hsm_id is required to scope it to one.
Receiving
Inbound WhatsApp messages arrive on your webhook like any other channel, with channel: "whatsapp". Nothing extra to configure.
Button and list taps arrive as ordinary inbound messages whose message is the label the customer tapped, so the simple path is to treat them as text. What makes them more useful is that each tap also carries replyTo, pointing at the message that offered the choice:
That matters for anything with repeated buttons. If you send five product cards each with a Buy button, the label alone cannot tell you which product they meant, but replyTo.messageId can.
Customer quote replies work the same way: when someone long-presses one of your messages and replies to it, replyTo points at the message they quoted.
Billing
WhatsApp conversation charges are billed by Meta directly to the payment method on your WhatsApp Business Account. They do not draw down AgentPhone credits, and they do not appear in AgentPhone usage.
If your WABA has no payment method, template sends fail with Meta error 131042. Session messages inside the window are free, so an unpaid WABA can look healthy right up until the first template send.
Limits
Not supported yet
- Group chats. WhatsApp’s Groups API requires an Official Business Account, which is a separate Meta application.
- Carousel templates. Horizontally swipeable cards, each with its own image and buttons. Use a stack of image-header button messages instead.
- Product and catalog messages. These need a Meta Commerce catalog attached to your WABA.
- Flows. Multi-screen forms authored in Business Manager.

