Inbound Routing
Callaro uses smart inbound routing to pick the right agent for an incoming call based on the caller’s recent context — not just the dialed number. This page explains how routing works, the layers involved, and how to configure or disable it.Why smart routing
Hubspot, Salesforce, and similar platforms route by active engagement, not by static DID-to-agent mapping. Callaro applies the same idea so that:- A contact returning a missed campaign call lands on the same agent that tried to reach them, with full context.
- A contact responding to a scheduled retry lands on the agent driving that campaign instead of a generic IVR.
- A contact replying to a follow-up lands on the agent who created the follow-up.
- Numbers that have no per-call context still fall back cleanly to the agent assigned to the dialed number.
inbound_routing_decision and shown on the call detail page.
How a decision is made
The resolver evaluates layers in this order. The first match wins.
Each layer enforces agent eligibility — the agent must be active, not archived, and have a published version. Ineligible agents cause the layer to skip to the next.
When multiple campaigns or follow-ups match (multi-campaign tenants), the resolver picks the most recently activated option as the tie-breaker.
The resolver is bounded by a per-layer 50ms timeout and a 200ms total budget. Anything slower automatically falls back to DID, and a metric is emitted (
inbound_routing.layer_timeout).
Tenant configuration
Tenant admins (and roles above) can change behavior under Tenant settings → Inbound routing.Routing mode
- Smart (default) — runs the layers above in order.
- Legacy DID — disables smart routing and always uses the agent assigned to the dialed number.
Default for all tenants issmart. This is the global flip — both new and existing tenants are migrated automatically. Switch tolegacy_didonly if your team has a workflow that requires the old behavior.
Layer toggles
You can disable individual layers without leaving smart mode (e.g. turn offlast_outbound if you don’t want recent-call attribution to override the DID).
Look-back windows
last_outbound_window_days— how far back to look for a recent outbound call. Default7.retry_window_hours— how soon aretry_pendingtask is considered “due”. Default24.
Engagement auto-unenroll
When a contact engages on a call (inbound answered, or outbound that reached a human and ran for ≥10 seconds), Callaro can automatically close other pending follow-ups for that contact. Theengagement_unenroll_scope setting controls how broadly:
Why
campaign is the recommended default:
- Each campaign has its own intent (sales sequence vs renewal vs survey). A return call for sales does not satisfy the survey objective.
- Each agent represents a distinct relationship (sales rep vs support rep vs account manager). Multi-agent setups exist precisely so different teams can engage independently.
- Same-campaign siblings (e.g. a call follow-up + an SMS follow-up scheduled by the same playbook) really were satisfied by the engagement, so they are completed rather than cancelled.
contact only if your business treats the contact as a single thread (one outreach conversation regardless of agent).
Contact memory scope
Independent of routing mode, you can pick how contact memory is shared between agents:exclusive(default) — each agent only reads memory it produced.shared— agents see a union of memory across the tenant, with provenance and concatenated free-text summaries.on_demand— same as exclusive at injection time, but the runtime can call a tool to fetch sibling memory when needed.
Emergency kill switch
The environment variableINBOUND_ROUTING_FORCE_LEGACY forces all tenants into legacy_did mode regardless of their setting. Acceptable truthy values: 1, true, yes, on. Use this only for incident response. Restart the API after toggling.
What appears in the UI
- Call logs: a
Routing reasoncolumn shows which layer won. - Call detail: the routing reason, agent, and a collapsible Routing decision trace show every layer that was evaluated, the result, and why.
- Campaign detail: an Inbound returns card shows how many inbound calls were attributed to that campaign, broken down by routing reason, with a link to the filtered call logs.
- Contact detail: the timeline annotates each inbound voice session with its routing reason badge.
Side effects on tasks and follow-ups
When an inbound call matches a campaign task or follow-up, the resolver closes the matched record at routing time:BulkCallTaskis markedcontacted_inbound. Abulk_call_task_eventis recorded with the inboundcall_sid, the matchedvoice_session_id(backfilled), andinbound_routing_decision_id.FollowUpis markedcontacted_inbound. Afollow_up_eventis recorded with the same cross-links.- Sibling follow-ups for the same
(contact, agent)are also closed implicitly with reasoncontacted_inbound_siblingso the contact is not double-pursued.
Follow-up uniqueness
Follow-ups now dedupe per campaign. The active uniqueness key is:(contact_id, agent_id, follow_up_type, bulk_call_campaign_id)
That means a contact in two different campaigns can have one active follow-up per campaign. Ad-hoc follow-ups (no campaign) continue to dedupe per (contact, agent, type).