WhatsApp Action

Sends WhatsApp messages through the WhatsApp Business API: text, images, audio, video, documents, location, reactions, and pre-approved templates. Which of them Meta will actually deliver depends on one rule, and it is worth reading before building anything.

Setup

A WhatsApp Business credential, from a Meta app with the WhatsApp use case (developers.facebook.com/apps). Its WhatsApp → API Setup page has the three values the credential asks for: an access token, the Phone number ID (a numeric id, not the phone number) and the WhatsApp Business Account ID. The token is checked against Meta when you save.

ℹYou can test without a number of your own. Meta gives every new app a free test number on that same page, and it can send to up to five numbers you add and confirm there. The access token it generates lasts 24 hours; for a flow that stays on, create a System User token in Business Settings. A number of your own must not be in use in the WhatsApp or WhatsApp Business app when you add it. The App Secret (App settings → Basic) is optional for sending and required by the trigger: Meta signs every message it delivers with it.

In Action mode, the Recipient is a country and a number: pick the country (the most used ones are on top, and you can search by name or code) and type the number as people write it there. For Mexico, the 10 digits — without the 1 WhatsApp still uses for Mexican mobiles; HostWebhook takes care of it. After a WhatsApp trigger, Reply to whoever wrote answers the sender ({{payload.from}}), and any value from the flow works too, as long as it ends up as the country code and the number, digits only.


Mode — action or AI toolkit

The Mode selector decides who drives the node. In Action mode you pick one operation and fill its fields, and the node does that every time it runs. In AI toolkit mode the operations become tools an AI Node can call, and the model chooses which one and with what arguments — but never who receives it. See AI toolkit mode.

ℹToolkit mode is opt-in per node, and it is what makes this node show up in an AI Node's tool picker. A node left in Action mode is invisible to agents.

Operations

The Operation dropdown decides what the node does and which fields appear under it. These are the exact values the API validates against:

ValueIn the dropdownWhat it does
sendTextSend text—
sendImageSend image—
sendAudioSend audio—
sendVideoSend video—
sendDocumentSend document—
sendLocationSend location—
sendTemplateSend template—
replyToMessageReply to message—
markAsReadMark as read—
sendReactionSend reaction—

⚠The 24-hour customer service window. Free-form messages — text, media, reactions — only reach a user who has messaged the business in the last 24 hours. Outside that window Meta blocks the send, and the only thing that gets through is sendTemplate with a template Meta approved in advance. This is a platform rule, not a HostWebhook one, and it is the single most common reason a WhatsApp flow “stops working”.

Sending a template

Pick the template from your WhatsApp Business Account's list — the approved ones first, each with its language (the same template in two languages is two entries) and a preview of its text. Refresh reloads the list after Meta approves a new one.

Its variables then show up one per field: {{1}}, {{2}}… or, for templates with named variables, {{first_name}}. Each takes a value or a template like {{payload.name}}.

ℹThe node fills the variables in the body. A template with an image, video or document header, or with a variable in its header or in a URL button, is flagged when you pick it: Meta would refuse the message, so pick one without it.

To take the template from the flow, choose Type the name instead under the list: the name, the language code and the variables — an array for {{1}}, {{2}}…, an object for named ones.


AI toolkit mode

In toolkit mode the node is ten tools an AI Node calls by name. They only answer the person who wrote. None of them has a recipient argument: the recipient is the sender of the WhatsApp message that started the flow, which the AI Node reads from its own input — so put the trigger in front of it. The model can't message anyone else, however it is asked to.

ToolArguments
send_whatsapp_texttext, previewUrl?
send_whatsapp_imageimage, caption?
send_whatsapp_audioaudio
send_whatsapp_videovideo, caption?
send_whatsapp_documentdocument, filename?, caption?
send_whatsapp_locationlatitude, longitude, name?, address?
send_whatsapp_templatetemplateName, languageCode?, bodyVariables?
reply_to_whatsapp_messagetext, replyToMessageId?, previewUrl?
mark_whatsapp_as_readmessageId?
send_whatsapp_reactionemoji, messageId?
  • Quoting, marking as read and reacting point at the message that started the flow unless the model names another one.
  • send_whatsapp_template starts blocked. Templates are paid, and the person just wrote, so the 24-hour window is open and a normal reply is free. Unblock it in the node's tool list if the agent should have it.
  • bodyVariables is a JSON list of texts, e.g. ["Ana", "ORD-1234"].
  • Refused, not sent: a tool called with no WhatsApp message in the flow (a Run Test, for instance), or when the message arrived at a different number than the node's credential.
  • Not over MCP. An MCP client brings no message to answer, so this toolkit isn't offered to MCP servers.

The trigger

A Trigger with the WhatsApp service fires when something happens on the number of its credential. Pick what fires it:

EventWhen
Message receivedSomeone writes to the number — text, a photo, a voice note, a document, a location, a contact, a reaction, or a button they tapped.
Message statusA message the number sent was sent, delivered, read, or failed.
Template statusMeta approved, rejected or paused one of the account's templates.

Activating connects the webhook for you — nothing to paste in Meta's console. HostWebhook registers its URL as your Meta app's webhook, verifies it, and subscribes the WhatsApp Business Account to the app. It needs the credential's App Secret, and every delivery's signature is checked with it before anything runs. Deactivating the app's last trigger disconnects the webhook.

⚠A Meta app has one webhook. Activating replaces any callback URL the app already had — if another tool receives this app's messages, it stops. Several triggers on the same app share the webhook, and each one only gets its own number's events.

What the trigger sends downstream

{
  "id": "whatsapp:message:wamid.HBgL…",
  "channel": "whatsapp",
  "event": "message",
  "messageId": "wamid.HBgL…",
  "type": "text",
  "from": "5215551234567",
  "name": "Jane Doe",
  "phoneNumberId": "106540352242922",
  "displayPhoneNumber": "15550783881",
  "wabaId": "102290129340398",
  "timestamp": "2026-09-29T14:20:42.000Z",
  "text": "Hi, has my order shipped yet?",
  "caption": null,
  "media": null,
  "location": null,
  "reaction": null,
  "reply": null,
  "contacts": null,
  "context": null,
  "raw": { "…": "the message exactly as Meta sent it" }
}

{{payload.from}} is who wrote and {{payload.messageId}} the message to quote, mark as read or react to. A photo, video (GIFs arrive as video), voice note, audio, document or sticker comes in media (its WhatsApp media id; voice is true for a voice note), and HostWebhook also downloads it as a file, like the Telegram trigger: {{payload.attachment._file}} (and the full list in attachments). The run history shows a preview, and an AI Node downstream reads it — it looks at the photo, reads the PDF, transcribes the voice note — with nothing else to wire. Files over 16 MB can't be virus-scanned, so they aren't downloaded; the reason is in _attachmentErrors and the message still goes through. A tapped button comes in reply. A status event carries status, recipient and any errors; a template event, templateName, status and reason.

ℹAnswering with an AI Node: trigger (Message received) → AI Node with this node as its toolkit. The AI Node reads the message, and every tool it calls goes back to whoever wrote.

Gotchas

  • No HTML. WhatsApp takes plain text with its own light markup: *bold*, _italic_, ~strike~.
  • Templates need approval before they exist. Create them in WhatsApp Manager; once Meta approves one, it appears in the node's list.
  • markAsRead is a courtesy that costs nothing — the blue ticks are the cheapest way to tell a customer the bot is alive.
  • Reactions need the inbound message id, which arrives in the trigger payload.