Workflow reference
This page lists everything you can use in a workflow and explains exactly how it behaves. To learn how to build one step by step, start with Workflows & automation.
How a workflow runs
Section titled “How a workflow runs”A workflow is a set of steps. Each step is one rule: trigger → conditions → actions.
- Something happens: a customer sends a message, a webhook is called, a follow-up falls due, and so on.
- Wabot finds the steps whose trigger matches. For messages, the channel and message type must match too. Only steps that are on, in workflows that are on, are checked.
- Each matching step checks its conditions. No conditions means it always runs.
- Every step whose conditions pass runs its actions, from top to bottom. It is not “first match wins”: if two steps match the same message, both run, in no guaranteed order. The Set up panel warns you when two steps start on the same message.
- If no step ran for a customer’s message, your AI bot answers it (when AI is on for the channel and the contact). If any step ran, even one that only adds a tag, the AI bot doesn’t answer that message.
How actions run
Section titled “How actions run”- Actions run in the order listed. If one fails, the next ones still run.
- Wait before sending is in seconds and is counted from the moment the trigger happened, not from the previous action. To send three messages a day apart, use 0, 86400 and 172800.
- Waiting messages are kept safely and are sent even if the server restarts. They are not cancelled if the customer replies or if you turn the step off, so keep sequences short.
- Only Send a template and Send a message can wait. Every other action runs straight away.
- Free-form messages (Send a message) only arrive within 24 hours of the customer’s last message. Outside that window, use Send a template.
Next steps
Section titled “Next steps”A step joined by a next step line (the Preceding Workflow condition in the form editor) runs only if the earlier step has already run successfully for the same contact.
- It still needs its own trigger, for example the customer’s next message or button tap. It doesn’t start by itself after the earlier step.
- There is no time limit: the earlier step can have run an hour or a month ago.
- Once unlocked, the step runs every time its trigger and conditions match.
- If several steps lead to it, all of them must have run.
- If the earlier and later steps both match the same message, both can run on it. Give the later step a different trigger, such as a button tap.
Runs and results
Section titled “Runs and results”Runs shows, for each step, who it ran for and the result of each action. A message counts as successful once it is handed to WhatsApp. If WhatsApp rejects it later (for example outside the 24-hour window), the failure shows in the chat, not in Runs.
Steps that start from the clock (No reply for a while, Follow-up is due), from Pipeline stage changed or from an integration send from your default WhatsApp number. No reply for a while uses the number the conversation was on, if it’s still connected.
Triggers
Section titled “Triggers”| Trigger | Runs when… | Settings | Gives these variables |
|---|---|---|---|
| Customer sends a message | A customer sends you a message on WhatsApp, Instagram or Messenger | Channel, message type, optional text to match | senderName, senderID and more by message type (see Variables) |
| Message is delivered or read | Any message you sent (from a workflow, a campaign, the inbox or the AI bot) is sent, delivered or read | None: use the Status and Template conditions | None |
| Started manually | You start it for chosen contacts or groups, from Contacts, a Meta lead form or Start another workflow | None | None (see Started manually) |
| Pipeline stage changed | A card is added to a pipeline or moves to another stage | Pipeline, stage type, from stage, to stage | deal_title, stage_name and more |
| No reply for a while | A conversation goes quiet for the time you set | Whose reply to wait for, how long | waiting_hours, waiting_since |
| Follow-up is due | A follow-up task reaches its due time, or is still open some time after it | When, how long overdue | followup_text, followup_due_at, followup_assignee, followup_overdue_hours |
| Webhook is called | Another system sends a POST with a JSON body to the step’s URL |
The URL (shown after the first save) | The fields of the JSON body, mapped under Variables |
| Webhook action replies | A Send to a webhook or Run code action in another step gets a reply | Add sample response to turn the reply’s fields into variables | response and each field of the reply |
| Integration events (e.g. Shopify order created, abandoned checkout) | A connected integration reports the event | None | The fields of the event |
Customer sends a message
Section titled “Customer sends a message”Fill in the sentence When a customer sends a channel message type message that match text.
Channels: WhatsApp, Instagram and Messenger. For Instagram, also choose how it’s connected: Instagram login or Facebook Page (the same option you used when linking it).
Message types
| Channel | Message types |
|---|---|
| Text, Click-to-WhatsApp ad message, Interactive quick reply buttons, Interactive list message, Image, Video, Document, Audio, Flow, Order, Payment | |
| Text, Quick Reply, Post Back, Comment, Image, Video, Document, Audio | |
| Messenger | Text, Quick Reply, Post Back, Comment, OptIn, Coupon, Image, Video, Document, Audio |
| WhatsApp message type | Runs when the customer… | Notes |
|---|---|---|
| Text | Writes a message | |
| Click-to-WhatsApp ad message | Sends the first message from your Click-to-WhatsApp ad | Adds the ad’s variables. If no ad step matches, Text steps answer it |
| Interactive quick reply buttons | Taps a reply button, in a message from a workflow or in a template | Match on the button’s title. button_reply_identifier holds what was tapped |
| Interactive list message | Picks a row from a list | Match on the row’s title |
| Image, Video, Document, Audio | Sends that kind of file | The caption is the message text. For audio, the text is the transcription if your plan includes it |
| Flow | Submits a WhatsApp Flow | Choose the flow under Select a flow. Each form field becomes a variable |
| Order | Places an order from your catalog | Use the Total Amount condition to check the order value |
| Payment | Pays (or fails to pay) for a catalog order | status is success, failed or pending. Payments for custom payment requests don’t start this trigger |
Stickers, shared locations, shared contacts and reactions don’t start workflows.
Text to match: contains, is exactly, starts with or is not. Leave it empty to run on every message of that type. Matching is case-sensitive (Price doesn’t match price), and spaces count. For button and list replies, the text is the button or row title.
Message is delivered or read
Section titled “Message is delivered or read”Runs for every status update of every message you send, including campaigns and the step’s own messages. Always add two conditions:
- Status: Sent, Delivered or Read.
- Template: the template you’re following up on.
Without them the step runs for every message of the account, and a step that sends a message can set itself off again.
Pipeline stage changed
Section titled “Pipeline stage changed”| Setting | Options |
|---|---|
| Pipeline | The pipeline to watch (required) |
| Only when the new stage is | Open, Won, Lost (none ticked = any) |
| From stage | Any stage (includes new cards) or one stage |
| To stage | Any stage or one stage |
A stage change made by a workflow starts other pipeline workflows only one level deep, so two workflows can’t keep moving a card back and forth. Needs Pipelines turned on in Settings → Pipelines.
No reply for a while
Section titled “No reply for a while”| Setting | Options |
|---|---|
| Start when | The customer hasn’t replied (after any message you send them, including campaigns) or Nobody has replied to the customer (any reply from your team, the AI bot or a workflow counts) |
| After no reply for | 5 minutes to 30 days |
Each new message restarts the wait. It runs once per silence: after it has run for a contact, it won’t run again until the other side writes. Because broadcasts also start the customer-side wait, add a condition such as Contact of a Group to limit it.
Follow-up is due
Section titled “Follow-up is due”| Setting | Options |
|---|---|
| Start | When it falls due, or When it’s still open after its due time |
| Overdue by | 5 minutes to 30 days (for the second option) |
Runs once per follow-up, for every follow-up in the account (including ones created by hand and by workflows) that is linked to a contact. In the “still open” case, nothing happens if it was completed in time.
Webhook is called
Section titled “Webhook is called”- Send a
POSTwith a JSON body to the URL. Wabot answers straight away and runs the step in the background. - The step runs only when both its switch and the workflow’s switch are on, and when its conditions pass. Conditions can use Variable and Preceding Workflow.
- Map the body’s fields under Variables with paths starting with
body., for examplebody.phonefor{"phone": "919876543210"}. - Tell the actions who to message with Phone number variable, e.g.
{{phone}}. The number must include the country code. A variable namednamegives a new contact its name. - Choose the sending number with Select Channel, or leave it empty for your default number.
- For an image, document or video, put the file’s public link in URL Variable: a variable such as
{{invoice}}, a fixed link such ashttps://example.com/brochure.pdf, or a link with variables such ashttps://example.com/invoices/{{order_id}}.pdf. - Hand off to an AI bot and Save data do nothing here: there’s no customer message to answer and no order to save.
- Free-form messages only arrive within the 24-hour window; to reach a new customer, send a template.
Webhook action replies
Section titled “Webhook action replies”Starts after a Send to a webhook or Run code action gets a reply. Paste an example reply with Add sample response: each field becomes a variable, e.g. {{response}} for the whole reply or {{order_id}} for response.order_id. A reply with an error code (4xx or 5xx) also counts. A timeout doesn’t.
Conditions
Section titled “Conditions”Conditions are extra checks under Advanced → Conditions. The step runs only if they pass.
What you can check
Section titled “What you can check”| Condition | Checks | Comparisons | Available on |
|---|---|---|---|
| Message Content | The message text, button or row title, or caption | is, is not, contains, does not contain, starts with | Customer sends a message, Message is delivered or read |
| Tagged Message | The conversation tags on the message | is any of, is none of | Customer sends a message |
| Contact of a Group | The contact’s groups | is any of, is none of | Customer sends a message, Started manually, Pipeline stage changed, No reply for a while, Follow-up is due |
| Channel | The number, Instagram account or Page the message came in on | is one of, is not any of | Customer sends a message, Message is delivered or read |
| Variable | Any of the step’s variables | is, is not, contains, does not contain, starts with, is greater than, is less than | Every trigger except Started manually and Message is delivered or read |
| Total Amount | The order total (price × quantity of every item) | is, is not, is greater than, is less than | Customer sends a message → Order |
| Status | The message status: Sent, Delivered, Read | is any of, is none of | Message is delivered or read |
| Template | Which template the message was | is any of, is none of | Message is delivered or read |
| Prompt satisfied | Whether the conversation meets a goal you describe, checked by AI | is met, is not met | Customer sends a message |
| Preceding Workflow | Whether earlier steps have run for this contact (see Next steps) | is | Every trigger except Started manually |
How comparisons work
Section titled “How comparisons work”| Comparison | True when… |
|---|---|
| is / is not | The value is exactly the text you entered, or isn’t. Case-sensitive, spaces count |
| contains / does not contain | The text appears anywhere in the value, or doesn’t. Case-sensitive. An empty value contains nothing |
| starts with | The value begins with the text. Case-sensitive |
| is any of / is none of | At least one of the chosen items applies, or none does |
| is one of / is not any of | (Channel) the message came in on one of the chosen channels, or on none of them |
| is greater than / is less than | Both sides are numbers and the comparison holds. Currency signs and thousands separators are ignored (₹1,250.50 = 1250.5). If either side isn’t a number, it’s false |
| is met / is not met | The AI judges that the conversation reaches the goal, or doesn’t. Each check uses an AI request |
Groups and AND / OR
Section titled “Groups and AND / OR”- Rules inside a group are joined with AND (all must be true) or OR (any one is enough). Groups are joined the same way. Up to 6 groups per step.
- The joins are read from left to right: A AND B OR C means (A AND B) OR C. To mix them differently, use groups.
- A missing join counts as AND.
- An OR next to a Preceding Workflow rule lets the step run without the earlier step. Keep the link joined with AND.
Actions
Section titled “Actions”| Action | What it does | Can wait? |
|---|---|---|
| Send a template | Sends an approved WhatsApp template to the customer or another number | Yes |
| Send a message | Sends a free-form message: text, media, buttons, a list, a catalog, a flow or a payment request (within the 24-hour window) | Yes |
| Add to groups or tags | Adds the contact to groups and tags | No |
| Mark as lead | Flags the contact as a lead, so it counts in lead reports | No |
| Assign to team member | Gives the chat to a teammate, takes turns, picks the least busy one, or unassigns | No |
| Create follow-up | Adds a task to the Follow-ups page | No |
| Move deal to stage | Moves the contact’s card to a stage, and can create one | No |
| Create deal | Adds a card for the contact to a pipeline | No |
| Mark deal won or lost | Moves the card to the pipeline’s first won or lost stage | No |
| Change deal owner | Gives the card to a teammate or to the chat’s assignee | No |
| Update deal value | Sets the card’s value to a number or a variable | No |
| Hand off to an AI bot | Lets an AI bot answer the conversation | No |
| Send to a webhook | Sends data to another system’s URL (REST or GraphQL) | No |
| Run code | Runs your JavaScript and passes its result on | No |
| Save data | Adds the message’s data to the customer’s order | No |
| Update a state value | Stores a value per contact or per workflow for later steps | No |
| Repeat a step | Runs another step’s actions again for this contact | No |
| Start another workflow | Runs a Manual workflow for this contact | No |
| Integration actions (e.g. Shopify) | Call the connected integration | No |
Send a template
Section titled “Send a template”| Setting | What it does |
|---|---|
| Send to | The customer (who started the step) or Another number (with country code, digits only) |
| Template | Any approved template |
| Wait before sending | Seconds, from the time of the trigger |
| Variables | Fill each template variable. For Name pick Customer name, Customer phone no. or Other; for Email Customer email; for custom variables type the value, or exactly one variable like {{senderName}} |
| Media | The header image, video or document, for templates that have one |
A custom variable must be exactly one {{variable}}. Text around it, as in Hi {{senderName}}, is sent as written. State variables and Flow answers can’t be used in templates. A missing value isn’t checked before sending, so WhatsApp may reject the message.
Send a message
Section titled “Send a message”| Message type | What you set | Limits |
|---|---|---|
| Text only | The text | 4096 characters |
| Media based | A file (image, video, document or audio) and its caption | Caption 1024 |
| Quick Reply | Header (text, image, video or document), text and buttons | Up to 3 buttons, 20 characters each |
| Call to Action | Header, text and one button with a link | Button 20 characters |
| Interactive List | Header, body, footer, sections with rows (title and description) and the button label | Row title 24, description 72 |
| Catalogue | A single product, several products or the whole catalog, with text | Needs a catalog linked to the number |
| Flow | Header, body, footer, the flow and its button text | Button 25 characters |
| Payment | Catalog Payment for the order just placed, or Custom Payment with your own items and amounts | Razorpay. Custom payments are in INR |
Instagram and Messenger have their own types: Text only, Media based, Quick Reply, Generic Template, Button Template, Comment Reply (to a comment), and on Messenger also Coupon, Receipt, Product and OptIn templates.
Variables work in the text and the caption. If any variable used there is missing or empty (or 0), the message isn’t sent and the run shows it as failed. Headers, footers, buttons and list rows are sent as written.
Send to a webhook
Section titled “Send to a webhook”| Setting | What it does |
|---|---|
| API type | REST or GraphQL |
| URL | Where to send. Can contain {{variables}} |
| Method | POST or GET (GET sends no body) |
| Headers | Key and value pairs. {{name}} in a header means a state value |
| Input data as | Body, Query or Path parameters (REST) |
| Payload / Query and Variables | The JSON to send. {{variables}} in it are filled in; unknown ones are sent as written |
The request times out after 15 seconds. To use the reply, start another step with Webhook action replies.
Team actions
Section titled “Team actions”Assign to team member
| Setting | Options |
|---|---|
| How to choose | A specific teammate, Round-robin (take turns), Least busy (fewest chats waiting for a reply), Unassign |
| Teammate(s) | One, or two or more for round-robin and least busy |
| Only if the chat isn’t assigned yet | Leaves chats that already have someone |
| Keep AI bot replies on | Off: assigning turns the AI bot off for that chat |
Create follow-up
| Setting | Options |
|---|---|
| Follow-up | What to do, up to 160 characters. Can use {{name}} (the contact’s name) and the trigger’s variables |
| Due in | 0 to 365 minutes, hours or days |
| For | The chat’s assignee (or the account owner), A specific teammate, or Nobody |
| Link it to the contact’s open pipeline card | Shows the follow-up on the card too |
Mark as lead has no settings.
Pipeline actions
Section titled “Pipeline actions”All need a Pipeline. When the step was started by Pipeline stage changed, they change that card. Otherwise they change the contact’s most recently updated open card in that pipeline, and do nothing if there isn’t one.
| Action | Settings |
|---|---|
| Move deal to stage | Move to stage; Create one in this stage if the contact has no open card (with an optional product and quantity) |
| Create deal | Stage (default: first open stage), Title (can use variables; empty = contact name and card label), Value, Owner, product and quantity, Skip if the contact already has an open card (on by default) |
| Mark deal won or lost | Won or Lost |
| Change deal owner | A specific teammate or The chat’s assignee |
| Update deal value | A number or a variable, e.g. {{order_total}}. ₹1,250.50 is read as 1250.5 |
Hand off to an AI bot
Section titled “Hand off to an AI bot”| Setting | What it does |
|---|---|
| Select AI bot | The bot that takes over |
| Idle Time and Time Format | How long the customer can be quiet before the bot hands back |
| Response Prompt Count | How many answers before the bot asks if the customer is satisfied |
| Exit Message | Sent when the idle time passes, with Yes and No buttons |
The bot answers the current message straight away, if AI is on for the channel and the contact and the message has text. Until the idle time passes or the customer taps Yes, their messages that don’t match another step go to this bot.
Data and workflow control
Section titled “Data and workflow control”| Action | Settings and behaviour |
|---|---|
| Run code | Your JavaScript. The step’s variables can be used in it, e.g. {{senderName}} or a webhook field such as {{order_id}}. Its result starts any Webhook action replies step linked to it |
| Save data | Orders: adds the incoming message’s data (such as an address from a Flow) to the customer’s order |
| Update a state value | Select a state variable and Value (one of the step’s variables). An empty value fails |
| Repeat a step | Runs the chosen step’s actions again for this contact, without checking its conditions. Don’t point a step at itself |
| Start another workflow | Runs the Manual workflow you choose for this contact, from the number you choose |
Variables
Section titled “Variables”Write a variable as {{name}}. The Variables section of a step lists the ones you can use, with a copy button.
Built-in variables
Section titled “Built-in variables”| Variable | Value | Added by |
|---|---|---|
senderName |
The customer’s WhatsApp profile name | Customer sends a message, Webhook action replies |
senderID |
The customer’s phone number | Same |
button_reply_identifier |
The button that was tapped | Interactive quick reply buttons |
ad_headline, ad_body, ad_source_url, ad_source_id, ad_source_type, ctwa_clid |
Details of the ad the customer clicked | Click-to-WhatsApp ad message |
Each Flow field, e.g. {{preferred_date}} |
The customer’s answer | Flow |
status |
success, failed or pending |
Payment |
response and each field of the reply |
The reply of the webhook or Run code | Webhook action replies (after Add sample response) |
| Each field of the event | The event’s data | Integration triggers |
deal_id, deal_title, deal_value, deal_currency, pipeline_name, stage_name, previous_stage_name, owner_name, deal_items |
The card that moved | Pipeline stage changed |
waiting_hours, waiting_since |
How long and since when the conversation has been quiet | No reply for a while |
followup_text, followup_due_at, followup_assignee, followup_overdue_hours |
The follow-up’s text, due time, assignee and hours overdue | Follow-up is due |
name |
The contact’s name (or number) | Always, in follow-up text and deal title and value |
Your own variables
Section titled “Your own variables”Click Add variable under Advanced → Variables. Names use letters, numbers and _, starting with a letter.
| Source | Value | Example |
|---|---|---|
| From trigger data | A path into the trigger’s data. The first part names where it comes from (messageMetadata., body., response., timer.), the rest is the field |
body.customer.email reads customer.email from a webhook body |
| Fixed value | The same text every time | A discount code |
Variables you add are kept when you change the trigger, channel or message type.
State variables
Section titled “State variables”States keep a value per contact (or per workflow) between steps and over time, for example the customer’s chosen language. Create them from States in a workflow card’s menu: State (the name), Value (the default), Type (e.g. Contact state) and Data type. Every step can use them as {{state}}; set them with Update a state value. They work in messages, conditions and webhooks, but not in templates.
Where variables work
Section titled “Where variables work”| Place | What’s available | If a value is missing |
|---|---|---|
| Send a message text and caption | Everything: trigger data, Flow answers, your variables, states | The message isn’t sent (failed) |
| Send a template variables | Trigger data and your variables (not Flow answers or states) | Sent empty, or as written if it isn’t one of the step’s variables; WhatsApp may reject it |
| Send to a webhook URL and payload | Everything | Sent as written, e.g. {{phone}} |
| Variable condition | Everything | The condition compares an empty value |
| Create follow-up text, Create deal title, Update deal value | name, the trigger’s variables (webhook, timer, pipeline, integration), your variables, states |
Left empty |
| Update a state value | Trigger data, your variables, states | The action fails |
| Run code | Trigger data (including a webhook body or reply), your variables, states | undefined |
Started manually
Section titled “Started manually”Manual workflows run for the contacts or groups you choose, from Contacts (Trigger Workflow), a Meta lead form or Start another workflow. They work differently from automatic ones:
- Only Contact of a Group conditions are used (with the first group chosen).
- Each action waits its time after the previous action. Leave the template wait at 0, because it’s applied twice.
- Send a message can’t use variables: a message with
{{variables}}stops the run. Templates can use the Name and Email presets and fixed values. - These actions work: Send a template, Send a message, Add to groups or tags, team actions and pipeline actions. Webhooks, Run code, AI hand-off, states, Save data, Repeat a step and Start another workflow are not run.
- Manual runs don’t show in Runs and don’t unlock next steps.
Limits
Section titled “Limits”| Item | Limit |
|---|---|
| Steps per workflow | 10 in the form editor |
| Condition groups per step | 6 |
| Quick reply buttons | 3 |
| Wait before sending | No maximum (in seconds) |
| No reply / overdue wait | 5 minutes to 30 days |
| Follow-up due | Up to 365 days |
| Follow-up text, deal title | 160 characters |
| Webhook timeout | 15 seconds; replies up to 64 KB are kept |
| Sending retries | 5 attempts, then the message is dropped |
Not available yet
Section titled “Not available yet”| You might want… | For now |
|---|---|
| A trigger at a date or time (e.g. an appointment reminder) | Create a follow-up for a teammate, or set a reminder from the inbox |
| To stop a sequence when the customer replies | Keep sequences short, and use No reply for a while for the nudge |
| A wait on team or pipeline actions | Use No reply for a while or Follow-up is due to act later |
| Order items as variables | Check the value with Total Amount |
| A payment trigger for custom payment requests | Only catalog orders start Payment |
| A trigger for stickers, locations, contacts or reactions | Not supported |
