Routing by called number, DTMF forwarding, and immediately rejecting the incoming call when the platform declines it require device gateway 1.3.5 or later.
How it works
The key is theagent_join callback: the gateway only hands the called number (no) and caller (name) to the platform. Your backend decides which channel the call joins and whether to answer it.
Three connection options
Dialing in to a meeting (entering the meeting ID after the call connects) needs an IVR to collect digits, which the customer’s PBX does before forwarding to the gateway; the gateway itself has no voice menu. AI calls don’t need digit collection—the conversation starts as soon as the call connects.
Gateway configuration
Configuration lives in the device gateway’soptions.xml; restart the gateway after changes.
Listening and public address
UseRtpAddress is true, the gateway sends voice back to the address the peer actually sends RTP from, so the peer can hear audio even behind NAT.
Which app incoming calls go to
Register to a carrier or PBX (optional)
Incoming-call IP allowlist (required for lines over the public internet)
Once the SIP port is exposed to the internet, it keeps receiving scanning calls. The gateway has a built-in automatic blocklist (an IP is blocked after more than 5 attempts in 30 seconds), so scans never reach the join flow. With a carrier line, the peer IP is fixed, so also turn on the allowlist to accept calls only from the line side:Your backend: one channel per call
On the AI phone app, configure callbacks and subscribe toagent_join. When the callback arrives:
- Check whether it’s a phone call:
typeis2(SIP), andnois the called number - Generate a unique channel name for the call, for example
phone-plus a random string - Call Get a channel join token with the
uidfrom the callback to get the device’ssid - Start the agent in the same channel asynchronously—don’t wait for the agent to join before returning
- Return
{"code": 0, "data": "<sid>"}from the callback; any non-zero return rejects the call, and the gateway responds with 603
__mcu__) in the channel for SIP devices, and it includes the agent’s own voice.
If the agent subscribes to all audio, filter by sender and feed only the device uid’s audio (the uid in the agent_join callback) into speech recognition;
otherwise the agent hears itself and interrupts itself.
DTMF
When the gateway receives a keypress, it sends a custom message to the channel as the device:
In the Python SDK, receive it with
on_custom_msg, for example to hand it to a pipecat pipeline:
Hang-up
- The caller hangs up: the device leaves the channel, and the agent ends the session when it receives the user-left event
- Your side hangs up (for example, after the AI says goodbye): call the Remove a user from the channel endpoint to remove the device uid from the channel, and the platform tells the gateway to send BYE on the line
FAQ
For SIP conferencing endpoint setup, see SIP / H.323 endpoints; for the AI side, see pipecat integration.