
GoHighLevel Workflow If/Else Conditions Guide (2026)
GoHighLevel Workflow If/Else Conditions Guide (2026)
By Dr Priya Jaganathan, GoHighLevel Certified Admin · HL Growth Partner, Australia · Updated 10 August 2026 · 8 min read
The GoHighLevel workflow If/Else action is the single step that turns a linear automation into something that behaves like a real process. Instead of sending every contact the same three SMS messages, you read what the record actually looks like at that moment and send them down the branch that fits. It is the cheapest, most reliable branching tool in the platform, and it is also the one I most often find misconfigured in accounts I audit.
Most of the trouble comes from a single misunderstanding: people treat If/Else as though it waits and watches. It does not. It is a snapshot test, evaluated once, at the instant the contact reaches that step. Once you internalise that, HighLevel If/Else conditions become predictable, and the rest of this guide is just knowing which filter categories exist, how branch order resolves, and when a different tool is the better answer.
What the If/Else action actually evaluates
When a contact hits an If/Else step, GoHighLevel reads the current state of that contact record and the current run's event data, compares it to your conditions top to bottom, and immediately routes the contact into the first branch that returns true. If no branch matches, the contact falls into the "None" (Else) path. There is no pause, no polling, no retry. The evaluation takes milliseconds.
That "current state" includes the contact's standard fields, custom fields, tags, DND and consent flags, associated opportunity data, appointment data, and the payload of the trigger that started the run. It is a read of the live record, not a copy taken at enrolment. So if a contact was tagged five minutes ago by a different workflow, the If/Else will see that tag. If the tag lands two seconds after evaluation, it will not.
Branch order matters more than people expect
An If/Else action can hold multiple branches, and they are evaluated in the order you have arranged them. Only the first matching branch fires. A contact who satisfies Branch 1 and Branch 3 goes down Branch 1 and never touches Branch 3. This is not a bug, it is standard first-match routing, but it produces a very common silent failure: someone puts a broad condition like "Tag is Lead" at the top and a specific one like "Tag is Lead AND Deal Value greater than 10000" underneath, then wonders why no high-value contact ever gets the premium sequence.
Rule of thumb: order branches from most specific to most general, and reserve the Else path for genuine exceptions rather than your main path. If your Else branch is carrying most of your volume, your conditions are wrong.
AND versus OR condition groups
Inside a single branch you can stack multiple conditions and join them with AND or OR. AND requires every condition to be true. OR requires any one. GoHighLevel also lets you build grouped logic — several conditions joined by AND inside one group, with groups joined by OR — which covers most real routing needs without resorting to nested If/Else actions.
Where people go wrong is mixing operators inside one flat list and assuming a precedence that is not there. If you need "(Suburb is Melbourne OR Suburb is Geelong) AND Service Interest is Implants", build that as two groups. Do not flatten it. When the logic starts needing three or more groups, that is usually a sign the decision belongs upstream — split the traffic at the trigger level instead.
The filter categories available in HighLevel If/Else conditions
The condition picker is organised into categories, and knowing what lives where saves a lot of scrolling:
Contact details. First name, last name, email, phone, company, address fields, source, assigned user, date created, date of birth, DND status per channel, and email validation status. These are the workhorse filters.
Custom fields. Every custom field on the sub-account appears here, typed according to how you built it — text, number, date, dropdown, multi-select, radio, checkbox. Number fields give you greater-than and less-than operators, which is what makes lead scoring possible. Date fields support before, after, and relative comparisons. If you built a field as text when it should have been a number, you lose those operators, and you will need to rebuild the field to get them back.
Tags. "Contact tag" with contains / does not contain operators. Tags are the fastest thing to evaluate and the easiest thing to let sprawl, which is why a disciplined GoHighLevel tags strategy pays for itself the first time you build a branching workflow across ten sub-accounts.
Opportunity and pipeline. Pipeline, current stage, opportunity status (open, won, lost, abandoned), lead value, and opportunity source. This is how you branch a follow-up sequence based on where the deal actually sits, which is far more accurate than inferring stage from tags. If your GoHighLevel pipelines and opportunities structure is clean, your If/Else conditions get much simpler.
Appointment. Appointment status (confirmed, showed, no-show, cancelled), calendar, and appointment start time. Essential for post-booking logic and for the show/no-show fork covered below.
Event and trigger data. Data carried by the trigger that started the run — inbound message body, form or survey field responses, the specific trigger link clicked, call duration and direction, payment amount, order product. This category is only populated when the workflow was started by a trigger that produces that data, which is why a branch on "Message Body contains STOP" returns nothing in a workflow started by a tag.
Attribution. UTM source, medium, campaign, term, content, referrer, and session source, on both first and last attribution. Useful for splitting paid traffic from organic in a shared nurture sequence.
If/Else vs Wait-for-condition vs Goal events vs separate workflows
If/Else is not always the right instrument. Four tools overlap here, and choosing wrong produces automations that technically run but never behave the way the business expects.
| Tool | Evaluates when | Best for | Avoid when |
|---|---|---|---|
| If/Else action | Once, instantly, at the moment the contact reaches the step | Routing on data that already exists — tags, custom fields, stage, consent, attribution | You are waiting for something that has not happened yet |
| Wait step with "wait for condition" | Continuously, until the condition is met or the timeout expires | Pausing until a reply, a tag, a payment or a field change occurs, then continuing on one path | You need three or more different outcomes from the same checkpoint |
| Goal event | Continuously, across the whole workflow, from any step | Jumping a contact out of a nurture sequence the moment they book, buy or reply | The "goal" is really just a routing decision, not an exit |
| Separate workflows | At enrolment, by trigger filters | Genuinely different processes — different owners, different reporting, different sub-account behaviour | The paths share 80% of their steps and will drift out of sync |
The practical test I use: if the answer is knowable right now, use If/Else. If you are waiting for a human to do something, use a Wait step with a condition or a Goal event. If the two paths would need different reporting or different people maintaining them, build separate workflows and stop trying to be clever.
Real builds where If/Else earns its place
Lead scoring routing
Maintain a numeric custom field, "Lead Score", incremented by other workflows on email opens, page visits, trigger link clicks and form completions. Your routing workflow then runs one If/Else with three branches: score greater than 60 goes to an internal notification plus an immediate call task; 25 to 60 goes to an accelerated SMS and email sequence; anything else drops into standard GoHighLevel drip campaigns in drip mode. One action, three commercially distinct outcomes.
Appointment show and no-show branching
After the appointment end time, add a Wait step of an hour or two, then an If/Else on Appointment Status. Showed goes to a proposal follow-up and an opportunity stage move. No-show goes to a rebooking sequence with a direct calendar link. Cancelled goes to a lighter re-engagement. The Wait step matters — evaluate too early and the status has not been updated by the front desk yet. This pairs naturally with your GoHighLevel appointment reminder workflows, which should already be handling the pre-appointment side.
SMS versus email based on consent
Branch on phone presence and SMS DND status. Valid mobile and SMS permitted goes to a LeadConnector or Twilio SMS. Everything else falls to a Mailgun email. Do not skip this branch in Australian accounts — sending to a contact who has opted out of SMS is a compliance problem, not a deliverability one, and the If/Else takes ninety seconds to build.
High-value versus low-value routing
Branch on Opportunity Lead Value or a qualifying custom field such as budget or number of locations. High-value leads get a human within minutes and a senior owner assigned. Low-value leads get self-serve content and a Conversation AI bot to handle first-line questions. The same logic sits well in front of a GoHighLevel database reactivation campaign, where the difference between a $500 and a $50,000 dormant record should absolutely change the messaging.
Industry branching in a shared snapshot
If you sell one snapshot to dentists, physios and chiropractors, do not build three workflows. Build one, set a custom field "Business Type" at import or intake, and branch messaging on it. Then push the copy differences into GoHighLevel custom values so the branch controls the logic while the custom values control the wording, business name, clinic address and booking link. Update the snapshot once and every sub-account inherits the fix.
The timing trap that catches everyone
Here is the failure I see most often. A workflow adds a tag at step 4, then an If/Else at step 2 checks for that same tag. Or worse: two actions in the same run, one setting a custom field and the next branching on it with no gap between them. The If/Else evaluates against the record as it exists at that instant, and asynchronous updates from other workflows, inbound webhooks or the API do not always land before the next step executes.
The fix is unglamorous and it works: insert a short Wait step — one to five minutes is usually plenty — between the action that writes data and the If/Else that reads it. If the write is coming from an external system, be more generous. And never branch on something the same workflow sets later; restructure so the write happens before the read, or move the decision into a second workflow triggered by the tag itself. The full behaviour of each trigger type is worth understanding here, and the GoHighLevel workflow triggers reference covers what data each one actually carries into the run.
Debugging branches that route the wrong way
Open the workflow, go to the Execution Logs tab, and find the contact. The log shows every step the contact touched, with timestamps, and crucially it shows which branch of the If/Else they entered. If they went down a branch you did not expect, you now know the condition returned true — so check the record's actual value rather than the value you assume is there.
Enrollment History is the second tool. It tells you whether the contact was enrolled at all, when, from which trigger, and whether they are still active in the workflow. Half the "my If/Else is broken" tickets I receive turn out to be "the contact never entered the workflow", usually because of a trigger filter or the re-entry setting.
Test with a real contact record, not a mental model. Create a test contact, set the fields deliberately, enrol it, and read the log. GoHighLevel's own help documentation is kept reasonably current on workflow action behaviour and is worth checking when platform behaviour changes, which it does. If you are weighing up which plan gives you the workflow volume you need, the GoHighLevel pricing page lists current tiers.
Keep branch counts low
Technically you can add many branches to one If/Else. Practically, past four or five the workflow becomes unreadable on the canvas and nobody on your team will touch it. When I inherit a workflow with an eight-branch If/Else and nested If/Else actions inside three of those branches, the rebuild is almost always faster than the debug. Prefer a small number of wide branches, name each branch descriptively rather than leaving them as "Branch 1", and move genuinely separate processes into their own workflows.
Common mistakes to avoid
- Putting the broad condition first. First match wins, so a general branch above a specific one makes the specific branch unreachable. Order most specific to least.
- Branching on data the same run sets later. The If/Else cannot see a tag or field that has not been written yet. Reorder the steps or add a Wait.
- Using If/Else when you needed a Wait-for-condition or Goal event. If/Else does not wait. If the answer is not knowable at that instant, you have chosen the wrong action.
- Leaving the Else path empty. Every contact who matches nothing silently exits the workflow. Give the Else path something — even a tag like "Unrouted" — so you can find them later.
- Branching on event data in a workflow that was not triggered by that event. Message body, form responses and trigger link data only exist when the matching trigger started the run.
- Hardcoding sub-account specifics inside branch conditions. Business names, links and phone numbers belong in custom values, not baked into a snapshot's If/Else logic.
If you want your GoHighLevel workflows rebuilt so the branching logic is clean, documented and safe to hand to your team, book a strategy call with the HL Growth Partner team.
Frequently asked questions
Does a GoHighLevel workflow If/Else check conditions more than once?
No. It evaluates a single time, at the exact moment the contact arrives at that step, and routes them immediately. It does not re-check later, and it does not wait for a condition to become true. If you need continuous evaluation, use a Wait step with a condition or a Goal event instead.
What happens if a contact matches two branches?
Only the first matching branch fires, evaluated top to bottom in the order shown on the canvas. The contact enters that branch and never touches the others. This is why branch order should run from most specific to most general.
Can I use AND and OR together in one branch?
Yes, using condition groups. Conditions inside a group are joined by one operator, and groups are joined by the other. Build "(A or B) and C" as two groups rather than a flat list, because a flat mixed list will not evaluate the way you expect.
Why does my branch on a tag never match even though the contact has the tag?
Almost always timing. The tag was added later in the same run, or by another workflow or API call that had not finished writing when the If/Else evaluated. Add a short Wait step before the If/Else, or restructure so the write happens before the read. Confirm in the execution log which branch actually fired.
Should I use If/Else or separate workflows for different service types?
Use If/Else when the paths share most of their steps and differ only in messaging — that is what custom values are for. Use separate workflows when the paths have different owners, different reporting requirements, or genuinely different process steps that would otherwise drift out of sync.
