Skip to main content

What routing does

Every ticket that lands in HaloAgents needs to end up somewhere: a specific inbox, a priority, a category, and (optionally) a teammate to own it. Routing rules are the engine that decides those four things automatically the moment a ticket is created. Routing happens once, at ticket creation. After that, anyone with permission can reassign manually. Rules don’t reroute tickets that already exist when you change the rules. Find it at Settings > Routing (/dashboard/settings/routing).

How rules evaluate

Rules are an ordered list. The first rule whose conditions match wins. Halo applies that rule’s actions and stops looking. Anything that doesn’t match any rule falls through to the implicit catch-all: the default inbox with no special priority, category, or assignee. This means:
  • Order matters. Move more specific rules above more general ones.
  • There’s no “and also.” Two rules can’t both match. The second one is ignored.
  • The catch-all is built in. You don’t need a rule like “everything else → default inbox”, that’s how the system already behaves.
You sort rules with the up and down arrows in the list. The numbered badge on each rule reflects its current priority.

Anatomy of a rule

Each rule has four parts:
PartWhat it does
TriggersWhich events run this rule. Today the only trigger is ticket.created, more are coming.
ConditionsA filter expression that decides whether the rule applies. Same builder as audience filters elsewhere in Halo.
ActionsWhat to set on the ticket when the rule matches. Up to four actions per rule.
EnabledAn on/off switch so you can keep a rule around without applying it.

Conditions

Conditions are built with the standard filter bar. You can mix:
  • Ticket fields: status, email_subject, email_body, source (email / widget / slack / etc.), priority, auto_created, and any custom field on the ticket via custom:<key>.
  • End user fields: name, email, plan, last_seen, mrr, arr, and any user trait via custom:<key>.
  • Company fields: company.name, company.domain, company.industry, and any company trait.
  • Stripe fields (when Stripe is connected): stripe:subscription_status, stripe:mrr, stripe:plan, etc.
  • Lead fields (for unidentified visitors): lead:lead_status, lead:lead_source.
Within a rule, you can group conditions with AND / OR for things like “plan is Enterprise OR mrr is greater than 1000”.

Actions

When a rule matches, any of these can be set:
ActionEffect
Assign to inboxMoves the ticket to the specified inbox. The default inbox is the catch-all if no rule matches.
Set priorityLow, Medium, High, or Urgent. Used in inbox filters and on the ticket badge.
Set categoryA free-form tag (e.g. billing, technical, feature_request). Useful for analytics and saved views.
Assign to teammatePre-assigns the ticket to a specific teammate. They’ll see it in their personal queue.
You can leave any action blank, only the ones you set are applied. The other fields fall back to defaults.

The dry-run preview

When you’re editing a rule, the right-hand panel shows a live preview computed against the last 30 days of tickets:
42 tickets in the last 30 days would have matched this rule. 6 would have been routed by an earlier rule first. 36 would actually be routed by this rule.
This is the most important UX in the whole settings page. It tells you, before you save:
  • How many tickets your rule actually catches.
  • How many it doesn’t catch because something earlier matched first (so you can move the rule up if needed).
  • Whether the rule is too broad or too narrow.
Tweak conditions or move the rule up and the numbers refresh on every change. If the preview hits a hard cap, you’ll see a “(truncated)” note, which means we sampled instead of scanning the whole window.

A practical example

Say you’re a support team that wants:
  1. Enterprise customers always go to the VIP inbox at Urgent priority.
  2. Anything mentioning “refund” or “cancel” goes to the Billing inbox.
  3. Anything from the widget on a logged-in Pro user goes to the Pro Support inbox at High priority.
  4. Everything else stays in the default inbox.
Your rules, top to bottom:
#NameConditionsActions
1Enterprise customersplan is enterpriseInbox: VIP, Priority: Urgent
2Billing keywordsemail_subject contains refund OR email_subject contains cancel OR email_body contains refundInbox: Billing
3Pro widget ticketssource is widget AND plan is proInbox: Pro Support, Priority: High
Rule 4 is unnecessary because the catch-all already routes everything else to the default inbox. If an Enterprise customer asks for a refund, Rule 1 wins because it’s first. That’s usually what you want, the VIP inbox sees the ticket and a Billing person can be CC’d. If you’d rather refunds always go to Billing regardless of plan, move Rule 2 above Rule 1.

Common patterns

Conditions: plan is enterprise. Actions: assign to a “VIP” inbox, priority Urgent. Add similar rules for Pro, Free, etc.
Conditions: email_subject contains refund. Actions: inbox Billing. Stack a few of these for password, import, integration, etc.
Conditions: stripe:mrr greater than 500. Actions: inbox High Value, priority High. Useful when “Enterprise” isn’t a clean enum on your end.
Conditions: source is slack. Actions: assign to the teammate who owns Slack support. Same idea for widget, email, or voice.
Conditions: auto_created is true AND lead:lead_source is pricing_page. Actions: priority High, assign to a sales-friendly inbox.
Today, “assign to teammate” picks one specific person. For round-robin, leave the assignee blank and let the inbox handle it via Auto-assign on reply instead.

Tips

  • Start broad, then refine. Get one or two big rules right (Enterprise, Billing) before micro-managing every category. Most of your tickets will fall through the catch-all and that’s fine on day one.
  • Watch the dry-run. If a rule says “0 would match”, check the conditions, you probably typed a value that doesn’t exist on tickets.
  • Disable, don’t delete. Toggle a rule off with the switch when experimenting. Easier to roll back than recreating it.
  • Read top to bottom. When you’re triaging an unexpected route, walk the list from rule 1 down. The first match wins.
  • Use “Test rule” before saving big changes. Editing a high-priority rule with a broken condition can dump everything into the wrong inbox. The preview is your safety net.

Permissions

PermissionWhat it lets you do
settings:viewSee the routing page and all rules.
settings:editCreate, edit, reorder, enable/disable, and delete rules.
Routing rules are workspace-scoped: every rule applies to every ticket in the workspace, regardless of inbox or agent.

Where to go next

Inbox Views

Configure the default inbox, auto-assign on reply, and saved views.

Escalation

How AI agents decide to escalate to a human in the first place.

Health Scores

Use health score in your routing conditions for at-risk customers.

Tickets

What teammates see once a ticket is routed.