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

# Inbound routing

> Use a workflow to choose which agent answers each inbound call.

Inbound routing runs a workflow at call time to decide which agent answers an incoming call. Each organization has at most one inbound-routing config. When a call arrives on one of your numbers, Anyreach passes the call details into your workflow, and the workflow returns the agent (and any per-call context) that should handle it.

Use this when a single number should route to different agents depending on who is calling, which number was dialed, the time of day, or any logic you can express in a workflow. If you do not need dynamic routing, assign an agent directly to a number instead — see [Telephony overview](/telephony/overview).

## How it works

When a call comes in, Anyreach checks for an inbound-routing config on your organization. If one exists and `enabled` is `true`, it runs your `workflow_definition`, feeds in the call details, and reads the workflow's output to resolve the agent.

```
inbound call
    │
    ▼
routing config exists and enabled?
    │ no ──────────────► (number's own assignment / disconnect)
    │ yes
    ▼
run workflow_definition  ── fails / times out ──► fallback_agent_id?
    │ returns output                                  │ set ──► fallback agent answers
    ▼                                                 │ empty ─► disconnect
reject == true ──► disconnect
    │ false
    ▼
agent_id (+ version, initial_context, custom_metadata) answers
```

The config is built and edited with the same workflow builder used elsewhere in the product, so the input and output of the routing workflow are fixed contracts. See [Workflows overview](/workflows/overview) for how to build the workflow itself.

## Workflow input

The workflow receives these fields on its `input` step:

| Field             | Type   | Description                                               |
| ----------------- | ------ | --------------------------------------------------------- |
| `caller_number`   | string | The phone number of the person calling in (E.164 format). |
| `called_number`   | string | The phone number that was dialed (your number).           |
| `trunk_id`        | string | The SIP trunk ID the call arrived on.                     |
| `organization_id` | string | Your organization ID.                                     |
| `timestamp`       | string | ISO 8601 timestamp of when the call arrived.              |
| `sip_headers`     | object | SIP headers from the inbound call.                        |

## Workflow output

The workflow's `output` step returns these fields. Every field is optional.

| Field                            | Type    | Default          | Description                                                                    |
| -------------------------------- | ------- | ---------------- | ------------------------------------------------------------------------------ |
| `reject`                         | boolean | `false`          | Set to `true` to decline the call. The call is disconnected and no agent runs. |
| `agent_id`                       | string  | —                | The agent ID to handle this call.                                              |
| `version`                        | number  | latest published | Agent version to use. Omit to use the latest published version of `agent_id`.  |
| `initial_context`                | string  | `""`             | Context injected into the agent's system prompt for this call.                 |
| `custom_metadata`                | object  | —                | Custom metadata attached to the resulting conversation.                        |
| `skip_pre_conversation_workflow` | boolean | `false`          | If `true`, skip the agent-level pre-conversation workflow.                     |

<Note>
  If the workflow returns neither `reject: true` nor a resolvable agent, the config's fallback agent is used. If there is no fallback agent, the call is disconnected.
</Note>

## Config fields

| Field                    | Type    | Required | Default | Description                                                                                                                         |
| ------------------------ | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `workflow_definition`    | object  | Yes      | —       | The routing workflow that picks the agent. Cannot be empty.                                                                         |
| `fallback_agent_id`      | string  | No       | `null`  | Agent used if the workflow fails or times out. Empty means the call is disconnected on failure.                                     |
| `fallback_agent_version` | number  | No       | `null`  | Version of the fallback agent. Omit to use its latest published version. Cleared automatically when `fallback_agent_id` is removed. |
| `enabled`                | boolean | No       | `true`  | When `false`, the config is ignored and the workflow does not run.                                                                  |

<Warning>
  The routing workflow runs only when a config exists **and** `enabled` is `true`. If the workflow throws or times out, Anyreach falls back to `fallback_agent_id`; with no fallback configured, the call is disconnected.
</Warning>

## API

All routes are org-scoped — the config is resolved from the organization on the token. There is exactly one config per organization. Authenticate with `Authorization: Bearer <token>`; user PATs (`pat_`) also require `X-Anyreach-Org: <organization_id>`.

| Method   | Path                           | Description                                  | Notes                                     |
| -------- | ------------------------------ | -------------------------------------------- | ----------------------------------------- |
| `GET`    | `/core/inbound-routing-config` | Get the config for the current organization. | Returns `null` if none exists.            |
| `POST`   | `/core/inbound-routing-config` | Create the config.                           | Returns `409` if a config already exists. |
| `PUT`    | `/core/inbound-routing-config` | Update the existing config.                  | Returns `404` if none exists.             |
| `DELETE` | `/core/inbound-routing-config` | Delete the config.                           | Returns `204`; `404` if none exists.      |

Reading requires the `inbound_routing_configs:read` or `inbound_routing_configs:manage` scope. Creating, updating, and deleting require `inbound_routing_configs:manage`.

### Create

```bash theme={null}
curl -X POST https://api.anyreach.ai/core/inbound-routing-config \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_definition": { "...": "..." },
    "fallback_agent_id": "agent_123",
    "fallback_agent_version": 4,
    "enabled": true
  }'
```

The response is the stored config:

```json theme={null}
{
  "id": "...",
  "organization_id": "...",
  "workflow_definition": { "...": "..." },
  "fallback_agent_id": "agent_123",
  "fallback_agent_version": 4,
  "enabled": true,
  "created_at": "...",
  "updated_at": "..."
}
```

### Update

`PUT` accepts the same fields, all optional — only the fields you send are changed. Set `fallback_agent_id` to `null` to remove the fallback agent; `fallback_agent_version` is cleared automatically when you do.

```bash theme={null}
curl -X PUT https://api.anyreach.ai/core/inbound-routing-config \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": false }'
```

## Related

<CardGroup cols={2}>
  <Card title="Telephony overview" icon="phone" href="/telephony/overview">
    Numbers, trunks, and how inbound and outbound calls connect.
  </Card>

  <Card title="Workflows overview" icon="diagram-project" href="/workflows/overview">
    Build the routing workflow and other automation.
  </Card>
</CardGroup>
