Skip to content
Expedify
5 min

WhatsApp Output

Replying on WhatsApp is the one channel where the product can refuse to send. Learn the 24-hour window first; the node's six fields take ten minutes after that.

Every other output node in this course sends when you tell it to. WhatsApp does not. There is a rule about when a business may speak to a customer, it is enforced inside Expedify rather than left to the provider, and a workflow that ignores it fails at the last step with the message already written.

So this lesson is mostly about that rule. The node itself is six fields and you will understand it in a minute; the reason WhatsApp automations break is almost never the node.

No workflow on this page. Every other lesson embeds one that really ran. WhatsApp needs a connected provider, and the tutorial organisation has none — so rather than show you a workflow nobody validated, this lesson stays with the configuration and the rule.

The 24-hour customer service window

A customer messages you. That opens a 24-hour window, and inside it you may send whatever you like — free text, media, whatever the workflow produced. When it closes you may send only a pre-approved template: a message whose wording was submitted to Meta in advance and accepted.

Three things about that rule cost people time:

  • Only a customer reply reopens the window. Sending a template does not. You can template someone daily for a month and the window stays shut for free text the entire time — until they answer.
  • The clock runs from their last inbound message, not from your last send. Expedify reads it from the conversation record, which an insert trigger keeps current. There is nothing to maintain, and nothing you can nudge.
  • The product blocks the send itself. This is not a provider rejection you find out about later. Before a free-form send the node checks the window; if it is closed the node returns a failure and leaves down its error path, and no message goes anywhere. Templates skip the check.

What you may send
Anything. Free text, and templates too.

What you may send
Still anything. The product tracks this state separately, which is what a “say it now” alert would key off.

What you may send
Templates only. A free-text send fails at the node.

What you may send
Templates only, permanently. Those two do not support free-form at all, so the window is irrelevant — see below.

Two providers never allow free text. AiSensy and Tata Tele are template-only, so a workflow that works on one BSP can fail on every send after you switch to another — with nothing about the workflow having changed. If your organisation is on either, build with use_template on from the start.

The six fields

integration_id

What it holds
WhatsApp integration to use for sending

message_content

What it holds
Custom message content (supports variables like {{response}}, {{contact.name}})

use_template

What it holds
Use WhatsApp template instead of plain text Defaults to false.

template_name

What it holds
Template name if using template

fallback_message

What it holds
Fallback message if no input provided Defaults to Thank you for your message. We'll get back to you soon..

add_typing_indicator

What it holds
Show typing indicator before sending Defaults to true.

Leave integration_id empty for the default provider. Set it only when you have more than one WhatsApp number connected and this reply must come from a particular one.

Turning on use_template changes what the node is. It stops sending your text and sends the approved template named in template_name instead, and it skips the window check. The template's variables come from the workflow, not from message_content — which is ignored entirely in template mode.

Where the message text actually comes from

This is the part that surprises people, and it is the opposite of how Text Response behaves. The node looks for text in four places and uses the first one it finds:

Source
message_content, if you filled it in. Templated, like everywhere else.

Source
The upstream node's output, read from any of six common keys: response, output, result, text, content, message.

Source
Response text left on the execution context by an earlier step.

Source
fallback_message — which has a default, so this node always sends something.

Leaving message_content blank is a real configuration, not an unfinished one. Put an AI node above this one, leave the field empty, and the model's answer goes to the customer. That is the shortest possible WhatsApp bot and it is why the field is not required.

It is also how a workflow sends something nobody wrote. Any upstream node that happens to emit an output or result key satisfies level 2 — including a node you added for a completely different reason. If a customer receives something odd, read the chain from the top and find which node owns the key.

What breaks

The fallback is a default, so silence looks like success. If nothing upstream produced text and you left message_content empty, the customer gets “Thank you for your message. We'll get back to you soon.” The run is green, the node reports a sent message, and the person waiting for an actual answer received a holding line. Change the fallback to something that reads as a failure to you — the word “sorry” and a way to reach a human — so you can spot it in the conversation log.

The typing indicator is a workflow-level setting wearing a node-level checkbox. It is applied at the webhook, before the workflow engine starts, by looking at whether the matched workflow contains any WhatsApp Output node with the flag still on. So unchecking it on one node of three changes nothing — the dot shows because the other two still want it. To suppress it, turn it off on every output node in that workflow.

A window failure is not a crash, and it is easy to miss. The node completes, returns success: false with the reason, and leaves down its error path. If nothing is wired to that path the run simply ends and the log shows a node that ran. Wire the error path to something — a task, an internal alert, a template send — or you will discover the problem from the customer.

Try it

  1. Connect a provider and message your own business number from your phone. That opens the window; everything below depends on it.
  2. Build the smallest loop: a WhatsApp trigger into a WhatsApp Output with message_content set to a fixed sentence. Confirm it lands.
  3. Now clear message_content and put any node above it that returns an output field. Send again and watch that node's output arrive on your phone — nothing configured it to.
  4. Wait out the 24 hours, or test against a number that has never messaged you, and send free text. Read the error the node returns: that message names the rule, and it is the one you will see in production.

Next: WhatsApp Question — the same channel when you want an answer back, and the workflow has to stop and wait for it.

Related lessons