Inbound Calling
How inbound calls work across all providers and how to configure webhook URLs and phone number routing.
What you'll learn
How zoxaAI receives and routes inbound phone calls, the universal inbound endpoint, provider-specific webhook configuration, automatic application creation, and the context variables available during inbound calls.
Inbound Calling
Inbound calling lets your zoxaAI agents answer phone calls automatically. When someone calls one of your configured phone numbers, zoxaAI detects the provider, matches the number, verifies the webhook signature, and starts the assigned agent.
How Inbound Calls Work
Caller Dials Your Number
A caller dials one of the phone numbers you have registered in a telephony configuration.
Provider Sends Webhook
The telephony provider sends an HTTP webhook (or ARI WebSocket event for Asterisk) to zoxaAI with the call details.
Auto-Detection
zoxaAI's universal inbound dispatcher auto-detects which provider sent the webhook by inspecting the payload structure and headers. No provider-specific URL is needed.
Number Matching
The called number is matched against all phone numbers registered across your organization's telephony configurations to find the correct configuration and phone number record.
Signature Verification
The webhook signature is verified using your stored credentials. This ensures the request genuinely originates from the telephony provider and has not been tampered with.
Agent Starts
The assigned agent starts, and bidirectional audio streaming begins between the provider and the voice pipeline.
Universal Inbound Endpoint
All providers use the same inbound endpoint:
https://your-domain.com/api/v1/telephony/runThis is a unified dispatcher — it auto-detects the provider from the webhook payload and routes the call accordingly. You do not need provider-specific webhook URLs.
When you create an inbound binding via POST /api/v1/call with type: "inbound", the platform installs this URL on the provider's side automatically — no manual dashboard step needed. The manual dashboard steps below are for when you configure the webhook directly on the provider instead.
Two equivalent inbound paths
Both /api/v1/telephony/run and /api/v1/telephony/inbound/run route to the same handler — configure a number with either one.
One URL for HTTP-webhook providers
Whether you use Twilio, Vonage, Plivo, Telnyx, Cloudonix, or Vobiz, you configure the same inbound URL. zoxaAI determines the provider automatically from the webhook payload. Asterisk ARI and Tata Smartflo are the exceptions — they stream over a WebSocket instead of an HTTP webhook (see their sections below).
Configuring Webhooks by Provider
Each provider has a different place in their dashboard to set the webhook URL. Below is a summary for each provider.
Twilio
| Setting | Value |
|---|---|
| Where to configure | Twilio Console > Phone Numbers > Active Numbers > select number > Voice Configuration |
| A call comes in | Webhook |
| URL | https://your-domain.com/api/v1/telephony/run |
| HTTP Method | POST |
Vonage
| Setting | Value |
|---|---|
| Where to configure | Vonage Dashboard > Applications > your application > Voice |
| Answer URL | https://your-domain.com/api/v1/telephony/run |
| HTTP Method | POST |
Plivo
| Setting | Value |
|---|---|
| Where to configure | Plivo Console > Voice > Applications > your application |
| Answer URL | https://your-domain.com/api/v1/telephony/run |
| Answer Method | POST |
Auto-configured for Plivo
If zoxaAI auto-created your Plivo Application (by leaving Application ID blank during setup), the webhook is already configured. No manual setup needed.
Telnyx
| Setting | Value |
|---|---|
| Where to configure | Mission Control Portal > Call Control > Applications > your application |
| Webhook Event URL | https://your-domain.com/api/v1/telephony/run |
Auto-configured for Telnyx
If zoxaAI auto-created your Call Control Application, the webhook is already configured.
Cloudonix
| Setting | Value |
|---|---|
| Where to configure | Cloudonix Dashboard > your domain > Voice Applications |
| URL | https://your-domain.com/api/v1/telephony/run |
| Method | POST |
| Type | CXML |
Auto-configured for Cloudonix
If zoxaAI auto-created your Voice Application, the webhook is already configured.
Vobiz
| Setting | Value |
|---|---|
| Where to configure | Vobiz Dashboard > your Application settings |
| Answer URL | https://your-domain.com/api/v1/telephony/run |
| HTTP Method | POST |
Auto-configured for Vobiz
If zoxaAI auto-created your Application, the webhook is already configured.
Asterisk ARI
ARI delivers call events over a persistent ARI WebSocket connection instead of an HTTP webhook. Asterisk ARI calls are not connected to agents -- see Asterisk ARI for details.
Tata Smartflo
Smartflo handles inbound calls over a static Voice Bot WebSocket — there is no HTTP webhook.
-
In the Tata portal, add a Voice Streaming endpoint (type Static) pointing at your Voice Bot URL:
wss://your-domain.com/api/v1/telephony/smartflo/ws?token=<config-token> -
Point your Smartflo DID at that endpoint. Incoming calls stream to zoxaAI, which resolves the agent assigned to the number.
See Tata Smartflo for full setup details.
Automatic Application Creation
For Plivo, Telnyx, Cloudonix, and Vobiz, when you leave the Application ID / Connection ID / Application Name blank during setup, zoxaAI automatically creates the application on the provider's side with the correct inbound webhook URL pre-configured.
| Provider | What Gets Created | Inbound URL Set To |
|---|---|---|
| Plivo | Plivo Application | https://your-domain.com/api/v1/telephony/run |
| Telnyx | Call Control Application | https://your-domain.com/api/v1/telephony/run |
| Cloudonix | Voice Application (CXML) | https://your-domain.com/api/v1/telephony/run |
| Vobiz | Vobiz Application | https://your-domain.com/api/v1/telephony/run |
This is the recommended approach for most users -- it eliminates the need for manual webhook configuration.
Number-to-Agent Routing
When an inbound call arrives, zoxaAI matches the called number against all phone numbers registered across your telephony configurations. For the call to route successfully, the number must be:
- Registered in a telephony configuration in your organization.
- Active (not disabled or deleted).
- Assigned to an agent.
Assigning a Number to an Agent
Navigate to Telephony
Go to Telephony in the zoxaAI sidebar.
Select Configuration
Click into the telephony configuration that contains the phone number.
Select the Phone Number
Find the phone number in the list and open it for editing (or click Add phone number to add a new one).
Choose an Agent
Select an agent in the Inbound target dropdown. This agent answers every call to this number.
Save
Save the phone number. Inbound calls to this number route to the selected agent.
Binding a number through the API
For Twilio, Vobiz, and Tata Smartflo numbers you can also bind a number to an agent with POST /api/v1/call and type: "inbound". An API binding takes precedence over the agent selected on the phone number.
Fallback Behavior
If a call arrives but routing fails, zoxaAI returns a provider-appropriate error response:
| Condition | Response |
|---|---|
| Number not registered | Provider-specific error message (e.g., TwiML <Say>) |
| Number not assigned to an agent | Provider-specific fallback response |
| Signature verification fails | Request rejected (HTTP 403 or provider-specific error) |
| Configuration credentials invalid | Provider-specific error response |
Context Variables
Every inbound call automatically receives these built-in context variables, accessible anywhere in your agent's configuration (including the system prompt) using {{variable_name}} syntax:
| Variable | Type | Description |
|---|---|---|
user_number | string | The phone number of the person calling |
agent_number | string | Your phone number that was called |
current_time | string | Current time (HH:MM, 24-hour) in the agent's timezone |
current_day | string | Current weekday name in the agent's timezone |
current_date | string | Current date (e.g., 12 December 2026) in the agent's timezone |
current_timezone | string | The agent's effective IANA timezone (e.g., Asia/Kolkata) |
Built-in variables always take precedence over values with the same name in the agent's saved context variable defaults. See Variable substitution for the full rules.
Using Context Variables in Prompts
You can reference these variables in your agent's system prompt:
You are a customer service agent for Acme Corp.
The caller's phone number is {{user_number}}.
Today is {{current_day}}, {{current_date}}.Cross-Organization Isolation
Inbound routing is strictly scoped to your organization. Even if two organizations use the same telephony provider and have the same account credentials, inbound calls are matched using the organization-specific configuration's account ID field. There is no cross-organization data leakage.
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Inbound calls not reaching zoxaAI | Webhook URL not configured on the provider | Set the webhook URL to https://your-domain.com/api/v1/telephony/run in your provider's dashboard |
| Calls arrive but get error response | Phone number not assigned to an agent | Select an agent as the phone number's Inbound target in your telephony configuration |
| Signature verification fails | Credentials mismatch or missing webhook public key (Telnyx) | Update credentials in zoxaAI; add the webhook public key for Telnyx |
| Wrong agent answers | Number assigned to the wrong agent, or an API binding overrides it | Update the phone number's Inbound target, or re-register the API binding with the right agent |
| "Phone number not found" | Number not registered in any telephony configuration | Add the phone number to your telephony configuration in E.164 format |