Conditions and variables
How a condition decides whether a workflow starts or which path a contact takes, and how a {{variable}} is filled into the text a workflow sends.
Getting here
Automate → Workflows, open a workflow. Conditions live in the trigger's Trigger Conditions section and inside the segments of a Condition step. Variables go into any message box, with the Variable button beside it.
Before you start
- An owner, admin or agent can add conditions and variables and save the workflow. Publishing that workflow — the thing that makes it run on live conversations — is an owner or admin action.
- Building and running workflows depends on your plan; see pricing.
- Nothing outside Inchat has to be connected. A condition or a variable only reads what the trigger, an earlier step or the contact already carries.
- Choose the trigger first. The list of fields a condition can read depends on it.
Set up
- For a rule on the whole workflow, open the trigger and expand Trigger Conditions. For a rule that sends contacts down different paths, open a Condition step and use one of its segments.
- Click Add condition. Choose a category, then the field, then how to compare it, then the value.
- With more than one condition in a list, say how they combine: Match all conditions or Match any condition on the trigger, all match (AND) or any matches (OR) on a segment.
- To put a variable in text, click into a message box, press Variable, search and pick the field. The box gets a token such as
$contact.name. - To cover a contact with no value, add a fallback after the name:
$contact.name||there. - Save, then publish. A saved but unpublished workflow starts for nobody.
Fields
- Category
- Groups the field menu: Incoming message, Question answer, Contact, Contact field, Channel, Conversation, Trigger details, AI reply, HTTP request, Quote and Other.
- Limits: A category with nothing to offer at this point of the workflow is not listed. Other always is.
- Field
- The one fact to test, such as the message text, a tag list, the channel or an order status.
- Limits: Shown as a menu only when the category has more than one field. In Other you type the path yourself.
- Comparison
- How to test it. The menu offers only the comparisons that fit the field: text, number, date, yes/no, a fixed set of answers, or tags.
- Value
- What to compare against. A field with a fixed set of answers shows them as a menu, and a yes/no field shows Yes and No.
- Limits: Hidden for exists and does not exist, which need none.
- Match all conditions / Match any condition
- How the conditions on the trigger combine. Match all conditions needs every row to pass; Match any condition needs one.
- Default: Match all conditions
- Limits: Offered only once the trigger has more than one condition.
How it works
- A condition is one row of four menus — category, field, comparison, value — saved as a field path, a comparison and a piece of text.
- The category menu lists Incoming message, Question answer, Contact, Contact field, Channel, Conversation, Trigger details, AI reply, HTTP request, Quote and Other, in that order, leaving out any that has nothing to offer.
- Contact, Channel and Conversation fields are offered for every trigger. Incoming message fields are offered for triggers that carry a message, and each family of triggers adds its own fields under Trigger details — the comment text for a comment, the order number for an order, the tag that changed for a tag update.
- Question answer, AI reply, HTTP request and Quote appear only when a step that produces them, such as Ask a Question or AI Reply, sits earlier on the path.
- Other takes any field path you type, for example
http.data.status, and saves it without checking that anything ever fills it. - The comparison menu depends on the field. Text offers is equal to, is not equal to, contains, does not contain, exists and does not exist. A number swaps the two contains options for is greater than, is greater than or equal to, is less than, is less than or equal to and is between.
- A date offers is after, is before, is between, exists and does not exist. A yes/no field offers only is equal to. Tags offer has tag, does not have tag, has any of, has all of and has none of.
- The value is always saved as text. exists and does not exist are the two comparisons that take no value.
- exists asks whether the field is present at all, not whether it holds any text: a field holding empty text counts as set.
- Text is compared without regard to capital letters or spaces around it, so is equal to
Aalso matches a reply ofaorA, and containsInselleralso matchesINSELLER. - is equal to on a number field compares numbers: the typed text
404matches a lookup that returned the number 404. Two pieces of text are still compared as text, so007does not equal7. - is equal to on a yes/no field compares the real yes or no, so choosing Yes matches a contact who agreed to marketing messages.
- contains on text matches a piece anywhere inside it. On a list such as tags it matches one whole entry, so
vipmatches a tag calledVIPbut not one calledvip-plus. - is greater than, is greater than or equal to, is less than and is less than or equal to read both sides as plain numbers.
- is between includes both ends and accepts them in either order. Written as text it is two values split by a comma or by two dots; the builder gives you two boxes instead.
- is before and is after compare moments in time, read from a date picker or from a stored date and time.
- has any of, has all of and has none of take a list separated by commas, compared without regard to capital letters, against a tag list or a single value.
- Trigger Conditions decide whether the workflow starts at all: the trigger fires, the conditions are read against that event, and the workflow only runs if they pass. With no conditions the workflow starts on every event of that trigger.
- Match all conditions is the default. Match any condition starts the workflow when one row passes, which is how a list of keywords is written as one row each.
- The ad triggers have no Trigger Conditions section, because the ad the contact came from is the entry. Conditions saved on one earlier still run, and the drawer names them with a Remove them button.
- Each segment of a Condition step has its own list of conditions and its own all-or-any choice, checked from the top: the first segment whose conditions pass takes the contact and the rest are not read. The Condition step's own article covers the paths themselves.
- A run carries its values with it. After a Wait or a question, later steps read the values captured when the run paused, not a fresh copy of the contact.
- The one value a run re-reads at the step is Agreed to marketing messages, because a contact can withdraw it during a long wait.
- A variable is written
{{contact.name}}or$contact.name, and either is replaced with that field's value at the moment the step runs. The Variable button writes the$spelling. - The Variable list offers the same fields the condition menu does, leaving out the channel, yes/no fields and the request status fields, plus the whole response of an HTTP Request.
- Braces work with any field path. The
$spelling is filled in only when the name starts with one of a fixed list of families — contact, conversation, message, channel, ad referral, answer, quote, AI, HTTP and saved answers among them — so a price such as$50stays as typed. - A variable with nothing to show takes its fallback:
{{contact.name||there}}or$contact.name||there. The fallback is used when the field is missing or empty, and a value of0orfalsestill shows as it is. - In the braces spelling a fallback runs up to the closing braces and may hold spaces. In the
$spelling it stops at the first space, so it can only be one word. - A field that holds a list or a group of values, such as a contact's tags or a whole HTTP response, is written out as JSON, so the placeholder shows you what you got rather than vanishing.
- A single value that is too long is cut short and ends in
…, so one lookup cannot take over the message. - Variables are filled into message text, file links and captions, template variables, internal comments, task titles and notes, and the value saved by Save to Contact Field.
When it fails
- A field the trigger or an earlier step never filled has no value. is equal to, contains, the number and date comparisons and exists then read as not matching, and nothing is reported.
- The opposite comparisons match a field with no value: is not equal to, does not contain, does not exist, does not have tag and has none of all pass. A mistyped path on one of them passes for every contact.
- When a trigger's conditions do not pass, the workflow does not start and nothing is sent to the contact. Open the workflow's Activity tab and look under Not triggered: the line reads Conditions did not match — the message read followed by the text it saw.
- The workflow panel on the conversation shows the same reason with the workflow's name in front. A draft or stopped workflow is never a candidate, so nothing is listed for one until it is published.
- When a trigger's conditions cannot be evaluated the workflow is skipped, and the Not triggered line reads Its conditions could not be evaluated (an error was logged).
- In a Condition step, a segment whose evaluation fails counts as not matching, and a contact that matches no segment goes down the None lane.
- A number, date or is between comparison whose text cannot be read as a number or a date does not error: it does not match.
- A variable with nothing to show and no fallback is replaced with nothing. The message still sends with a gap where it was, and the placeholder text is not left in. Some fields log a warning naming the variable and the conversation when it comes up empty: the text, caption or header of a message sent to the customer, a Send WhatsApp Template step's variables, and an internal note's text. Everything else is filled the same way but logs nothing, including a task's title and notes, a file URL, and a Start a WhatsApp Chat step's phone number and template variables.
- Saving is refused when a comparison other than exists and does not exist has an empty value: The condition on "<field>" needs a value.
- A Condition segment with no conditions is refused with “Segment 1” needs at least one condition (the name is the segment's own, or Segment and its number).
- Publishing a Message received workflow with no conditions and no channel chosen is refused with This workflow runs on every inbound message in the workspace. Add at least one condition (for example "Message sender is customer" plus a keyword or a channel) before publishing.
Limits
- The comparisons are the fixed set above. There is no arithmetic, no wildcard or pattern matching, and contains is a plain match.
- The value is compared exactly as typed. A
{{...}}variable typed into a value is not filled in, so a condition cannot compare one field against another. - One list is all-of or any-of, never a mix, and lists do not nest. Two rules joined differently need two segments or two steps.
- Only the trigger's list and a segment's list have the all-or-any choice. An older Branch step, which is no longer in the add-step menu but still opens and edits, checks all its conditions and sends the rest to its Else path.
- A manual Run a workflow does not read the trigger's conditions on the message or on trigger details, because there is no triggering message. It checks only the Contact, Channel and Conversation conditions, requires all of them even when the trigger says Match any condition, and lets you go past a mismatch with Enrol anyway.
- Contact values in a run are frozen at the moment it started and are not re-read as the run goes on. A Tag Contact or Save to Contact Field step earlier in the SAME run does not become visible to a later Condition in that run, any more than a tag a teammate adds during a Wait does. Only Agreed to marketing messages is re-read.
- Numbers are read as plain numbers. Text such as
1,200or a value with a currency sign is not a number, so a greater-than or less-than on it does not match. - A variable is not filled into the address, headers or body of an HTTP Request; those are sent as typed.
- The
$spelling cannot carry a fallback with a space in it; use the braces spelling for a phrase. - The
$spelling is not filled in for every field the Variable button lists. Deal, comment, payment, link, video and shipment fields, and the changed-tag and changed-field details, are outside the list, so$deal.valuegoes out as typed. Write{{deal.value}}for those. - The builder limits how many conditions one list can hold and refuses to save a longer one.
Best practices
- Narrow the trigger itself where it offers a scope, such as the channels it listens on, and use conditions for the rest, so a Message received workflow does not read every message in the workspace.
- Write a keyword rule as one row per keyword with Match any condition, not as one row with all the words in it.
- Give every variable that may be empty a fallback, and read the message as the contact will:
Hi {{contact.name||there}}reads well with or without a name. - Prefer the positive comparison when the field might be missing: has tag
vipsimply does not match a contact without the field, while does not have tagvipmatches them. - When a workflow does not start, open Activity and read what the trigger actually saw before changing a condition that seems not to match.
Use cases
- Start a workflow only for messages that mention a product: Incoming message → Message text contains the product name, with another row for each spelling and Match any condition.
- Send a returning customer down a different path: a Condition step with a first segment for Contact → Total orders is greater than a number, and everyone else on None.
- Greet Sarah Chen by name without leaving a gap for a contact with no name:
Hi {{contact.name||there}}, thanks for reaching out. - Quote a value an HTTP Request step already looked up in the next message, such as
Current status: {{http.data.status}}.The request itself cannot be personalised this way — its address and body are sent exactly as typed, never filled with{{contact.phone}}or anything else — so this only works for a lookup that does not need to know who is asking. - Lock a workflow to one number: Channel → Channel is equal to the connected number.
FAQ and troubleshooting
- My condition never matches, though the message looks right. Where do I look?
- Open the workflow's Activity tab and read Not triggered: it shows the text the trigger saw. Then check that the field is one this trigger fills — a field it does not fill has no value and never matches a positive comparison. Capital letters and spaces around the text do not matter.
- Why does a does not equal or does not contain condition match every contact?
- Those comparisons pass when the field has no value. If the path is mistyped, or belongs to another trigger, there is never a value, so the condition is true for everyone. Check the field in the menu, or use the positive comparison.
- Will my customer ever see
{{contact.name}}in a message? - Not a well-formed one: a field path spelled with only letters, numbers, underscores and dots, like
contact.name, is replaced with nothing when it has no value, or with its fallback when it has one. A path with a space or a hyphen in it is not recognised as a variable at all and is sent exactly as typed, braces and all — stick to plain field names, and add a fallback such as{{contact.name||there}}to avoid a gap. - Which should I use,
{{contact.name}}or$contact.name? - Either. Both are filled in the same way at the moment the step runs. The Variable button inserts the
$spelling, and the braces spelling is the one to use for a fallback made of several words. - How do I match any of several keywords?
- Add one contains row per keyword under Trigger Conditions and choose Match any condition. In a Condition step, choose any matches (OR) on the segment.
- Do capital letters matter in a condition?
- No. Text is compared without regard to capital letters and without the spaces around it, so
VIP,vipandvipare the same to a condition.
Related
- Condition — Split the run into up to twelve lanes plus a None lane, checked top to bottom — the first lane whose conditions all pass wins, and Condition tests one field against one value at a time.
- Workflows: how a flow runs — A workflow is one trigger, optional conditions and an ordered list of steps; only a published workflow runs, and this article explains how a run starts, forks, pauses, fails and stops.
- Build a workflow with AI — Describe a flow in plain words and the assistant drafts it for you to review: the draft sits in the side panel until you put it on the canvas, nothing is saved until you press Save, and nothing runs on customers until the workflow is published.
- Workflow triggers — The 34 events a workflow can start from — what each one actually watches, what it exposes to conditions and messages, and where it quietly does nothing.
- Avoid workflow loops — What already stops a flow from re-triggering itself, and the two hard caps — on Jump To and on Trigger Another Workflow — that stop a deliberate loop from running forever.
Reading this with an AI assistant? Plain Markdown version.