Workflow conditions and filters
Conditions decide exactly which replies a workflow touches. There are 28 of them, from labels and sentiment to time since the last reply, target account domains, campaign names, the day of the week and who sent the message. Combine any of them with AND, OR and NOT.
- Combine conditions with AND, OR and NOT, and nest them in groups.
- A failed condition can be re-checked after 2 and 5 minutes with Retry on condition failure, for labels that land a moment after the message.
- Conditions only match prospects who have replied, so a workflow with conditions never touches someone who never answered.
- Meeting triggers, New Reminder and Found Phone Number run without conditions over the API.
The reply
| Condition | What it checks | Comparisons | Example |
|---|---|---|---|
Labelslabels | Which labels the thread has right now. | equals, not equals, any of (OR), not (NOT), is empty, not empty | Only run when the thread is labeled Interested or Meeting Request. |
Label sentimentlabel_sentiment | Whether the thread's label is positive, neutral or negative, so one rule covers every positive label you create. | equals positive, neutral or negative | Alert Slack for any positive label, now and when you add new ones. |
Message textmessages | Keywords in the prospect's messages. | contains, does not contain, AND, OR, NOT | Route replies that mention "pricing" or "contract" to a senior rep. |
Subjectsubjects | Keywords in the email subject line. | contains, does not contain, AND, OR, NOT, is empty, not empty | Treat subjects containing "Book a demo" as inbound form leads. |
Read or unreadseen | Whether anyone on the team has opened the thread. | equals read or unread | Escalate interested replies that are still unread. |
Has a drafthas_draft | Whether a reply draft, written by a rep or a reply agent, is waiting on the thread. | equals yes or no | Ping the rep only when an AI draft is ready to approve. |
Timing and status
| Condition | What it checks | Comparisons | Example |
|---|---|---|---|
Last message fromlast_msg_from | Who sent the latest message in the thread. | equals me or prospect | Only remind the rep when the prospect spoke last. |
Ongoing conversationongoing_conversation | Whether there is a real back and forth, or only your outbound messages. | equals yes, no or only sent | Skip threads where the prospect never replied. |
Time since a replyreply_since | How long since the last message, your last reply, or their last reply, in minutes, hours or days. | less than, greater than, equals, not equals, between | The prospect replied more than 4 hours ago and nobody has answered. |
Last message datelast_message | The date of the latest message in the thread. | between, equals, not equals, before, after | Only act on conversations from this quarter. |
Reminderreminder_at | Whether a follow-up reminder is set on the thread, and when it is due. | due in, past due by, not set | Find positive replies with no follow-up reminder set. |
Message countscount_by | How many replies, sent messages or follow-ups the thread has. | equals, less than, greater than, between | After 3 follow-ups with no answer, move the lead to Nurture. |
Day of weekIn the appday | Which day the event happened. Set in the app on Incoming Message and Add Label workflows. | any of Monday to Sunday, in the workspace time zone | Weekend replies get an instant acknowledgement and a Monday reminder. |
The prospect
| Condition | What it checks | Comparisons | Example |
|---|---|---|---|
Prospect namename | The prospect's name. | equals, not equals, contains, starts with, ends with, AND, OR, NOT, is empty, not empty | Exclude test leads named "Test". |
Prospect emailemail | The prospect's email address. | equals, not equals, contains, starts with, ends with, AND, OR, NOT, is empty, not empty | Only run for prospects with a work email. |
Company domaindomain | The domain of the prospect's email. | equals, not equals, starts with, ends with, contains, AND, OR, NOT, is empty, not empty | Target account list: alert the account owner when any of 50 domains replies. |
Custom fieldscustom_fields | Any custom field on the prospect, by field name. | equals, OR, is empty, not empty | Only push leads to the CRM when Company size is filled in. |
Phone numberIn the appphone | Whether the lead has a phone number yet. Set in the app. | is empty, is not empty | Interested and no phone: run phone enrichment first. |
Assigned memberIn the appassigned_member | Which rep owns the lead. Set in the app. | is a member, unassigned, anyone | Notify only the owner's Slack channel, or alert the manager about unassigned positives. |
Call history and outcomeIn the appcall_outcome | Calls made with the MI Inbox Dialer and their outcome. Set in the app. | called or not, by outcome | No answer on the call: send an SMS and set a reminder. |
Where it came from
| Condition | What it checks | Comparisons | Example |
|---|---|---|---|
Campaign namecampaign_name | The sequencer campaign the reply came from, by name. Empty means the email came in outside any campaign. | equals, not equals, contains, AND, OR, NOT, is empty, not empty | Send replies from Enterprise campaigns to the enterprise channel. |
Channelchannel_id | The mailbox or LinkedIn account the reply landed in. | equals, not equals, any of (OR), not (NOT) | Replies to one rep's mailboxes go to that rep. |
Source toolsource | Which integration the reply came through, such as Instantly, Smartlead or HeyReach. | equals, not equals, any of (OR), not (NOT) | Handle HeyReach LinkedIn replies differently from email. |
Sequencersequencer | Whether the lead is in a Smartlead or lemlist sequence. | is or is not Smartlead or lemlist | Pause the Smartlead campaign only for leads that are in one. |
Sent fromsent_from | How an outgoing message was sent, including through the API or one API key. | equals Master Inbox, a rep by hand, a reply agent, or the API | Log every message your own automation sent through the API. |
Listinbox_type_id | Which list the thread sits in, such as Call/Reply or Meeting Booked. | equals, not equals, any of (OR), not (NOT) | Only alert on threads in the HOT list. |
Folderfolder | Whether the thread is in Archive, Marketing, Spam or Trash. | equals, not equals, any of (OR), not (NOT) | Never act on anything in Spam. |
Chili Piper link and meeting typeIn the appchili_piper | Which Chili Piper link or meeting type produced a booking. Set in the app on Meeting Booked. | workspace, meeting type, scheduling link | Bookings from the phone team's link stop the email follow-up. |
Conditions in an API request
Each rule is keyed by any short id you choose. This one matches positive replies from your target accounts where the prospect spoke last:
{
"conditions": {
"a1": {
"field": "label_sentiment",
"operator": "AND",
"condition": "equals",
"values": [
"positive"
]
},
"b2": {
"field": "domain",
"operator": "AND",
"condition": "equals",
"values": [
"northwind.com",
"tallbridge.com"
]
},
"c3": {
"field": "last_msg_from",
"operator": "AND",
"condition": "equals",
"values": [
"prospect"
]
}
}
}
The full list of allowed values is live at GET /workflows/filter-fields. Reference: workflow API guide.
Questions
How many conditions can one workflow have?
As many as you need. Combine them with AND, OR and NOT, and nest them in groups, the same way you build views in the inbox.
Can I use conditions through the API?
Yes. Send them in trigger_config.conditions on the create-workflow request. Conditions marked In the app are set in the workflow builder.
Why did my workflow not run for a prospect who never replied?
Workflows with conditions only match prospects who have replied. Leave conditions off to act on everyone.
See conditions in real workflows
Browse 177 workflows sales teams run.
