Quick answer: Code-based routing — match a keyword, take a branch — works until real customer language drifts off the keywords you hardcoded. Intent-based routing replaces the keyword list with an AI classification step: you declare the intents you serve ("billing", "support", "booking"), the classifier picks the one a message actually means, and the flow routes down a named edge per intent. On Orbit the routing decision is observable — the flow's step trace records which intent matched, which edge the run took, and when the fallback fired — so the routing model is auditable, not a black box. The skill is declaring good intents and designing the fallback, and the fallback decision belongs to you.
An inbound message arrives on one of your numbers, and your flow has a decision to make: what is this, and where should it go? The two answers to that question — a condition written in code against raw text, or an AI classifier asked to judge intent — differ less in accuracy than in how they fail and how you can see the failure. This post walks both models as they actually run in a visual flow builder, then designs two live flows — a support-intent router and a booking classifier — and closes with an honest look at how competitor flow builders frame the same choice.
What a visual flow builder does, and how executions actually flow
The Orbit Flow Builder is a drag-and-drop canvas: you place a trigger node, place action, AI, and logic nodes below it, and connect them by dragging from one node's output handle to the next node's input. Triggers start the flow — an incoming SMS, WhatsApp, or email, a webhook, a cron schedule, a platform event. Actions do something — send a message on any channel, make a call, or invoke an external API. Logic nodes shape the graph — condition, split, merge, delay. You test the flow with sample data before it touches live traffic, then publish.
Routing is where the canvas earns its keep. Every routing decision in either model — code-based or AI-based — is a graph question: when this node produces an outcome, which outgoing edge does the run take? That is why the comparison between the two models only makes sense grounded on the same graph semantics, and why Orbit's edge behavior matters more than any UI.
Once a published flow starts on live traffic, every run is recorded as an execution — its status, its duration, and a step-per-node trace listing each node's input, output, and any error. The trace is what turns routing from a guessing game into an inspectable decision: when a customer says "my bill is wrong again," and the run took the billing edge, you can see it.
The AI Classify node: intents as edges, fallback as a designed path
Orbit ships an AI Classify node in the builder's AI palette. You configure it with the list of intents you serve, and it reads the inbound conversation and classifies it against that list. The graph semantics are the whole story:
- One edge per intent you declare. If your intent list is billing, support, booking, the node exposes one outbound edge named for each, and you draw each to its destination.
- A designated fallback edge. When none of the named intents matches the message, the run takes the node's fallback edge — the path you drew for "we don't know what this is."
- A no-result edge. When the classifier produced nothing usable, the run takes a separate no-result edge, so a classification outage degrades to a designed path too.
- Unlabeled default edge as last resort. If neither a matching named edge nor a fallback is drawn, the run takes the node's unlabeled default edge; if no default exists either, the run ends there.
Every handle-and-fallback decision lands in the run's step trace, so a misrouted branch is inspectable per node: "did the billing edge fire," "did we fall through to the fallback," "did the classifier return nothing." The classification is still probabilistic — but every outcome is a drawn edge, and every choice the runtime made is recorded.
Intent routing versus code routing, side by side
A code-based router uses a condition node: test the raw message against a keyword or a field value, and branch yes/no per condition. An AI-based router uses the classify node: declare intents, route one edge per intent, and design the fallback. The differences that actually matter in production:
- The keyword list versus the intent list. Code routing's classifier is a keyword list a human wrote. Intent routing's classifier is a model asked "which of the intents you declared best describes this message." The first fails when real language drifts off the keywords; the second fails when the intent list does not actually describe what customers send. Both lists need owning; only the second fails with a designed fallback.
- The deterministic choice versus the probabilistic choice. A keyword match is deterministic — the same input always routes the same way. A classification is probabilistic — the same input may route differently at different times. Determinism is a debugging benefit; for routing, the worse debugging story of the probabilistic model is exactly what the step trace compensates for.
- The fallback is a drawn path in both models. The code router says "if no keyword matched, the no-edge fallback sends this to support." The classify router says "if no intent matched — or the classifier returned nothing — the fallback edge sends this to support." Both designs have to decide what the fallback route does; one does not let you skip that choice.
- The step trace is the debug interface either way. For a code route, the trace shows which condition fired. For an AI route, the trace shows which intent matched, which edge the run took, and when the fallback fired. Either model is auditable; neither is a black box on this runtime.
The call you actually make when you pick one over the other: hardcoded keywords drift with language you did not predict; declared intents drift with intents you did not list. One model's risk is phrasing; the other's is taxonomy — and the fallback is the designed answer to both.
Worked example one: a support-intent router
A three-intent support router on inbound SMS:
- Trigger. Incoming SMS on one of your numbers.
- Classify. Declared intents:
billing,technical,account. - Route.
- billing edge → send to the billing queue. - technical edge → send to the technical queue. - account edge → send to the account queue. - Fallback edge → send to the general queue with a "we weren't sure what this was" tag attached.
- The trace answers "why." When a run goes to the billing queue, the trace records which intent matched. When it goes to the general queue, the trace records which edge was missing — the fallback fired because no intent matched, or the classifier returned nothing.
That is the whole design. Three named intents, one fallback, every route recorded — and the fallback goes somewhere a human owns, not a dead end.
Worked example two: a booking classifier
A single-purpose booking classifier on inbound SMS:
- Trigger. Incoming SMS.
- Classify. One declared intent:
booking. - Route.
- booking edge → run the booking-step chain (check availability, confirm). - Fallback edge → send to the general support queue, with the same "not a booking request" tag.
- One intent is enough. You do not need to declare the full universe; the fallback handles the rest by design.
Single-intent classifiers are not a degenerate case — they are the common case when the flow serves one purpose and everything else is "not my case." The classifier still declares a named edge; the fallback still answers "not this."
Where this sits against competitor flow builders
The intent-versus-code question is not specific to Orbit — it is the question every visual flow builder answers. The honest competitive read:
Twilio Studio, the closest competitor flow builder on a CPaaS, routes on two primitives: a keyword/regex widget evaluated against message text, and a branching widget evaluated against flow variables. That works exactly like the code-based model above — the designer enumerates what to match. Twilio's own public docs frame AI-based routing as an extension you wire in with a function call, not a first-class node. That is an honest product choice, and the split between Orbit's classify node and Twilio's widget-based routing is a real, checkable difference — one platform ships classification in the palette, the other ships matching in the palette. Orbit's own Twilio comparison page and best Twilio alternatives guide weigh CPaaS platforms on shipped, checkable capabilities rather than positioning; this is the same frame applied to flow builders, where the difference is which routing primitive ships as a node.
Competitors are not wrong — code routing is a legitimate model that ships on a large share of the industry's flow builders, with deterministic behavior and a human-authored match list. The frame here is that intent routing is a different primitive: a classify step whose output is one of the intents you declared, and whose failure modes (a bad intent taxonomy, or a classifier that returned nothing) degrade to a designed fallback path, recorded per run. Any buyer putting flow builders on a shortlist gets a real, concrete question out of it: does the routing ship as a node, or as a function you call and hope?
Frequently asked questions
What is intent classification?
Intent classification is routing a message by what it means rather than which keywords it contains. You declare the intents you serve — billing, support, booking — and a classifier picks the one that best describes the inbound message. It replaces a keyword list with a taxonomy.
Why is code-based routing a problem in production?
Hardcoded keyword lists fail on real customer language: the customer writes "my bill is wrong again" and your list matches "invoice." The routing bug is silent until someone reads fallback traffic by hand. An intent-based model still fails — but on a designed fallback path, recorded in the trace.
Can I mix code routing and AI routing in the same flow?
Yes. Chain a condition node before the classify node — for example, "skip classification when the message is STOP" — and let anything else classify. Each model decides a different edge; the graph composes them the same way.
What should the fallback edge do?
Send the message to a queue a human owns — general support, a triage queue, an unclassified inbox — with a low-confidence or unmatched tag attached. The fallback should degrade to a human decision, not drop the run. Anything more specific defeats the point of having a fallback.
How do I know which intents to declare?
Rank by what your inbound traffic actually sends — the last 60–90 days of inbound messages grouped by theme — and declare the intents that cover it. Declare too few and the fallback absorbs real traffic; declare too many and two intents compete for the same messages.
What does the step trace actually show for a classify node?
For each run, the trace records the classify step with its input (the message), which intent matched, and which edge the run took — the named edge, the fallback when no intent matched, or the no-result edge when the classifier produced nothing. A misrouted branch is a recorded decision, not a mystery.
Does every flow builder have a classify node?
No — and the distinction matters when you shortlist. Twilio Studio, the closest CPaaS flow builder, ships keyword and variable branching as widgets; Orbit ships classification as a first-class node. That difference shows up in your routing taxonomy, not your messaging reach.
The takeaway
Intent-versus-code routing is a taxonomy question, not a keyword question. A visual flow builder makes the taxonomy a drawn graph: declared intents, one edge per intent, a fallback for whatever did not fit, and a trace that records every choice. Code-based keyword routing is a legitimate model shipped by every major CPaaS — but if your flow builder's routing primitive is a match list rather than a classify node, the bugs are silent. If you build routing flows at all, the step trace is what keeps either model honest — the flow isn't a black box when every routing decision lands in the audit.
Published 24 August 2026.