Open in
Connect from Zoom Contact Center
Send Zoom Contact Center calls to a ThunderPhone agent with a third-party voicebot connector, and take them back to a human agent with a SIP REFER.
A Bot widget in your Zoom Contact Center flow sends the caller to the agent with
Zoom's call sid. When the caller needs a person, the agent sends a SIP REFER
to Zoom's human-agent address, and your flow fetches the hand-off by call sid.
Before you start
- A ThunderPhone agent and an organization API key.
- A Zoom Marketplace General App, managed by your admin and made available to Contact Center, with a connector for the Bot widget (Zoom's third-party voicebot guide).
- A SIP trunk from Zoom to the bot provider. Zoom's ISV team builds it in stages (discovery, a staging trunk, then production), and the app's Company Name must match the trunk record exactly. This setup starts with ThunderPhone support and Zoom, not in your Zoom account alone.
1. Create the SIP endpoint
Zoom's connector dials a 15-digit number starting with 999, not a SIP
address. Saving the connector generates that number. Zoom's trunk uses TLS 1.2
on port 5061 with SRTP for audio, and is allowlisted by Zoom's subnets rather
than a password. So create an ip_allowlist endpoint with the connector's
number as a dial-in number and SRTP required (see
Platforms that dial a phone number):
curl -X POST https://api.thunderphone.com/v1/sip-endpoints \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": 12,
"name": "Zoom Contact Center",
"auth": "ip_allowlist",
"allowed_source_cidrs": ["ZOOM_SIGNALLING_RANGE_1", "ZOOM_SIGNALLING_RANGE_2"],
"dial_in_numbers": ["999123456789012"],
"srtp": "required"
}'allowed_source_cidrs: Zoom's SIP signalling subnets, from Zoom. Each must be a public IPv4 range of/16or narrower (IPv6/48or narrower).dial_in_numbers: the connector's number exactly as Zoom sends it, without a+.srtp:required, since Zoom's trunk always uses SRTP.
Zoom's addresses are shared by all its customers, so any other Zoom customer who dials the number reaches your agent. Zoom assigns the number; don't publish it.
2. Send calls with context
Add a Bot widget to your flow and bind it to the connector. Ask Zoom's ISV
team to point the trunk at sip.thunderphone.com, TLS on port 5061, with the
connector's number in both the request URI and the To header. The endpoint
refuses UDP, so make sure the trunk doesn't fall back to it.
Zoom sends:
X-ZOOM-Call-Sid, stored as the call'sexternal_call_id. Zoom's own data mapping page doesn't list it; another AI provider's Zoom integration documents it, so check it on your first test call.X-ZOOM-DNIS, the number the caller dialed, as{{sip_x_zoom_dnis}}.X-ZOOM-WEBHOOK, the connector's Static URL.
3. Get the call back
The agent sends a REFER to the human-agent address on Zoom's SBC. Add this
transfer number (see
Add the transfer number),
with the SBC address Zoom gives you:
{"name": "Zoom human agent", "number": "sip:HumanAgent@203.0.113.10:5061"}Zoom's guide describes two ways a bot passes context: a POST to the
connector's Static URL before the REFER (voicebot_metadata and similar
events), and SIP headers mapped under Inbound from Bot. ThunderPhone
doesn't post to the Static URL. Zoom's guide doesn't say whether it reads
mapped headers from a REFER; if you want to try, add headers such as
"X-Handoff-Id": "{{handoff_id}}" to the entry and check on a test call. Also
confirm with Zoom that it accepts a REFER with no metadata POST before it.
To get the hand-off without relying on either, have your flow look it up after the Bot widget, with an HTTP Call or Script widget:
GET https://api.thunderphone.com/v1/calls/handoff?external_call_id=followed by the call sid.- Header
Authorization: Bearer sk_live_…. - Use
handoff.summaryandhandoff.intentto route the caller and brief the person who takes the call.
Zoom doesn't publish field-level docs for these widgets, so confirm in your
account that the widget can send an Authorization header. See
Look up a handed-off call.
Test it
Call a number that reaches the Bot widget, ask the agent for a person, and check
that the caller reaches a human agent and the widget returns the hand-off. Then
open the call with GET /v1/calls/{call_id}: sip_headers should list
x-zoom-call-sid, and external_call_id should match the call sid your flow
uses.
Limits
- ThunderPhone doesn't post to the connector's Static URL, so Zoom gets the
hand-off through the lookup, or through mapped headers if your test shows
Zoom reads them from the
REFER. - The trunk is built by Zoom's ISV team, so you can't set it up or test it on your own.