> ## Documentation Index
> Fetch the complete documentation index at: https://help.callaro.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Inbound runtime vars

# Inbound Runtime Variables

When an **inbound** call is bridged to an agent, Callaro passes a set of `runtime_vars` to the voice runtime in addition to the usual variables. Your prompt can branch on these to greet the caller appropriately, acknowledge the campaign they're returning to, or skip the introduction entirely.

These variables are **only present on inbound** calls. Outbound prompts continue to use existing campaign/contact variables.

## Variables

| Key | Type | Description |
| - | - | - |
| `direction` | string | Always `"inbound"` for inbound calls. |
| `routing_reason` | string | Which layer of smart routing matched. One of `active_campaign`, `retry_pending`, `active_followup`, `last_outbound`, `did_fallback`, `no_active_match`. |
| `routing_layer` | string | Same as `routing_reason` but stable across renames; safe to switch on. |
| `inbound_routing_decision_id` | integer | DB id for the persisted decision trace; useful for support tickets. |
| `contact_id` | integer or null | Matched contact, if found. |
| `campaign_id` | integer or null | Matched `bulk_call_campaign_id` (when `routing_reason` is `active_campaign` or `retry_pending`). |
| `task_id` | integer or null | Matched `bulk_call_task_id` (when applicable). The task is closed as `contacted_inbound` before the agent picks up. |
| `follow_up_id` | integer or null | Matched `follow_up_id` (when `routing_reason` is `active_followup`). The follow-up is closed as `contacted_inbound` before the agent picks up. |

The full list of canonical contact variables (e.g. `contact.first_name`, `contact.metadata.*`) is also resolved when a contact is matched.

## Sample prompt branches

You can branch greetings and intent based on `routing_reason`. Pseudocode for the agent prompt's opening lines:

```text theme={null}
{{#if routing_reason == "active_campaign"}}
Hi {{contact.first_name}}, thanks for calling back about
{{campaign.name}} — I was just trying to reach you.
{{else if routing_reason == "retry_pending"}}
Hi {{contact.first_name}}, perfect timing — I had a follow-up
scheduled for you on {{campaign.name}}.
{{else if routing_reason == "active_followup"}}
Hi {{contact.first_name}}, thanks for calling back —
I had a follow-up note for our last conversation.
{{else if routing_reason == "last_outbound"}}
Hi {{contact.first_name}}, thanks for getting back to me.
{{else}}
Hi, you've reached {{agent.name}}. How can I help?
{{/if}}
```

For non-conversational logic (tools, branches), prefer `routing_layer` since the value is stable across product renames.

## Tips

* The `task_id` and `follow_up_id` are **already closed** by the time the agent answers. Do not call task-completion tools again — instead, use the IDs to look up history when you need it.
* `direction == "inbound"` is the easiest gate to keep inbound-only language out of outbound prompts.
* For DID fallback (`routing_reason == "did_fallback"`), most inbound-specific variables are null. Treat it like a cold inbound call.
* If you see `routing_reason == "no_active_match"`, smart routing decided no agent was eligible; the call was bridged to the DID's agent (or unknown agent) anyway. This is rare and usually indicates an agent went inactive between the inbound webhook and the bridge.

## Related articles

* [Inbound Routing](https://help.callaro.ai/phone-numbers/inbound-routing.md)
* [Prompt writing fundamentals](https://help.callaro.ai/scripts-and-ai/prompt-writing-fundamentals.md)
* [How the AI handles calls](https://help.callaro.ai/scripts-and-ai/how-the-ai-handles-calls.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.