Journey-driven dispatch
When a journey reaches a send node, Active Reach has to decide which channel to deliver on, when, and with what fallback if the primary delivery fails. Journey-driven dispatch is the system that makes that decision for every send — coherently, across channels, with the customer’s signals in the loop.
What it replaces
The earlier model treated every send as independent: each channel had its own delivery logic, its own retry behaviour, and its own opinion about whether the contact was reachable. The result:
- A contact got the same message on WhatsApp and SMS because neither knew about the other
- A high-intent prospect waiting on a chat reply got a transactional bump message that broke the conversation flow
- Cart recovery sent via email even when the contact had an active WhatsApp session 10 seconds ago
Journey-driven dispatch unifies this — every send node consults a single dispatch policy that knows the contact’s recent channel activity, current chat session state, and any pending warm-offer the operator has staged.
How dispatch resolves a channel
When a journey enters a send node, the engine evaluates:
- Chat-first rule — if the contact has an active WhatsApp or in-app chat session within the last N minutes, the message routes to chat regardless of the send node’s nominal channel. Reason: don’t break a live conversation by sending the same thing on SMS.
- Warm-offer queue — if the operator has staged a higher-priority message for this contact (e.g. a tier-protection notice, a paid-membership renewal warning), it’s delivered first; the journey send is queued behind.
- Channel preference — the send node’s configured channel is attempted (WhatsApp, SMS, email, push, in-app).
- Channel reachability — if the configured channel is unreachable (opted out, invalid number, capped by cross-campaign suppression), fallback to the next channel in the contact’s preference order.
- Frequency cap — if delivery would exceed the contact’s frequency cap, the message is delayed (typically until the next day’s window opens).
- Send — message is queued for the channel provider; webhooks track delivery.
You see this entire decision chain on the contact’s timeline for any send — including which rules fired and why.
Chat-first behaviour
The chat-first rule is the most opinionated piece. It says: if a contact is mid-conversation, every journey send routes to that conversation instead of sending a separate transactional message.
Concretely:
| Scenario | Without chat-first | With chat-first |
|---|---|---|
| Contact replies to a WhatsApp ad → reaches an agent → journey fires “your order shipped” SMS | Two separate channels, two unrelated threads | The “order shipped” arrives in the same WhatsApp thread the agent is on, in context |
| Contact in active in-app session → journey fires push notification | Push notification + in-app surface fight for attention | In-app surface wins, push is suppressed (re-sent only if in-app is dismissed without read) |
The chat-window length is configurable per workspace (default: 60 min).
Warm-offer queue
A warm offer is a message the operator has staged outside any journey — typically a CSM outreach, a tier-upgrade nudge, or a renewal warning. Warm offers wait for the next dispatch opportunity (a journey send, a session-start trigger, etc.) and ride along with it instead of generating a separate touch.
Why this matters: customers who get both a journey send and an operator-staged message in the same hour view it as spam. The warm-offer queue collapses these into a single, higher-priority delivery.
Operators stage warm offers at Contacts → {contact} → Stage warm offer or in bulk at Outreach → Warm offers.
Frequency caps and gradual silence
Every contact has a frequency cap (configurable per-workspace; defaults vary by tier). When the cap is hit:
- Soft messages (promotional, lifecycle) — queued for the next day’s window
- Hard messages (transactional, security, payment-related) — bypass the cap
If a contact repeatedly hits the cap, the system enters a gradual silence — promotional touch frequency decays exponentially until a positive signal (a click, a reply, a purchase) re-opens the channel.
Configure caps at Settings → Channels → Frequency caps.
What you see in the journey editor
The send node UI surfaces the dispatch policy:
- A chat-first toggle (on by default for relationship channels — WhatsApp, SMS — off for one-shot channels like email)
- A warm-offer collapse toggle (on by default)
- The channel preference order as a drag-list — operators see the fallback chain before publishing
- A dry-run button that runs the dispatch policy against a sample contact and shows which rules fire
Observability
The journey analytics dashboard at /dashboard/[ws]/journeys/{journey}/analytics shows for every send node:
- Sent / delivered — by primary channel + fallback channels
- Suppressed — by reason (frequency cap, opt-out, chat-first deferred, warm-offer collapsed)
- Re-delivered — sends that fell back from one channel to another
Use the analytics to tune the send node: a high suppression-by-frequency-cap rate suggests too many concurrent journeys; a high chat-first-deferred rate suggests journeys conflicting with live support sessions.
What’s next
- Send node — node-level configuration that interacts with dispatch
- Cross-campaign suppression — how suppression segments factor in
- Channels overview — channel-by-channel behaviour
- How Actii decides — the higher-level decision system