Offers: the right upsell, at the moment the customer is already talking to you
Cross-selling has a trust problem. Most of it is a banner screaming at someone who came to fix something else. The offers module takes a different route: it shows an offer at the exact moment a customer has already told you what they need — because they're in the middle of a guided flow, telling you.
How an offer happens
A customer runs a flow — say, "troubleshoot my slow drain." They answer a few questions. At the right step, the system checks your offer catalog: which offers are active, and which ones match this customer's answers using the same condition rules your whole workspace shares. If a matching offer exists — a drain-snake kit, an inspection visit — it appears in the conversation, naturally, right where the customer just admitted the problem.
That last part is the trick. Offers aren't spam; they're answers to a question the customer literally just asked. The targeting conditions read the answers the flow collected. Change the answers, change the offer.
The analytics don't lie
I want to brag about one design decision. The module records "shown" every time an offer is displayed — and if an offer was skipped for any reason (inactive, missing, not matching), it is never counted as shown. So your numbers mean what they say: shown means a human saw it, accepted means a human took it. When the report says an offer converts, you can believe it, because the denominator wasn't inflated by offers nobody ever saw.
Every shown and accepted event lands in the offer events log, so "which offers actually pull" is a query, not a debate.
Where it connects
Two connections run this module. The catalog is where offer products come from — the offer targets catalog items, so pricing and descriptions stay true no matter where they're shown. The flows module is where offers appear — a flow is a conversation, and the offer is one line in it. If you write a new flow for a common problem, you've also written a new shelf for your best-fit add-on.
And the loop closes with me: when I'm talking with a customer in the widget or walking them through a flow, offers surface the same way — evaluated against their answers, never pushed before there's something real to attach to.
Why this beats the banner
Because it respects the sequence. The customer describes the problem; the flow understands it; the offer solves the next part of it. Nobody gets sold a maintenance plan before they've told you their water heater is leaking. Your conversion numbers go up because the timing went right, not because the pixel went orange.
The targeting rules themselves are the same condition system the rest of the workspace speaks — flow decisions, ticket assignment rules and offer targeting all share one rule format, so the syntax you learn once works everywhere. And the engine stays honest about what it knows: offers resolve at runtime against the live catalog, so an inactive product can never be offered, and a skipped offer is filtered out before it can pollute a single statistic.
Related: offers sell from the catalog and appear inside flows — the two modules that make the timing work.
How this compares
Cross-sell tooling usually lives in marketing software — e-commerce upsell apps and automation platforms like Klaviyo are good at showing things to people. Their model is broadcast: segments, campaigns, emails. What a small service business usually has instead is a conversation — a customer in the middle of a guided fix, asking the obvious follow-up question. Broadcast tools aren't watching that moment.
The offers module is. Offers attach to guided flow steps and fire while the customer is actively working the problem, which is the moment intent is real. Under the hood they use the same condition DSL that drives flow decisions and ticket routing — one rule format, not three. And the analytics are careful in a way I respect: an offer only counts as "shown" when it actually rendered and matched, so your conversion numbers measure the truth instead of the aspiration. Skipped offers never pollute the rate. If you sell physical goods, the catalog gives offers something real to attach to — products with stock awareness behind them. A banner app can't see the flow; that's the whole difference.
Try it
Offers live under Offers in your sidebar. Create one from a catalog product, give it targeting conditions, and run the flow it targets — you'll see the offer appear exactly where the answers make it relevant, and the analytics tab start counting honestly.
