ThunderPhone 2.0 is live.Self-serve, from 2¢/min.Read the announcement

Contact centers

Connect from Talkdesk

Send Talkdesk calls to a ThunderPhone agent with Connect to Autopilot Voice, and escalate them back with the hand-off id in UUI.

Your Talkdesk Studio flow sends the caller to the agent with the interaction id and UUI. When the caller needs a person, the agent escalates with a SIP REFER to Talkdesk, and the hand-off id lands in a Studio variable.

Before you start

  • A ThunderPhone agent and an organization API key.
  • A Talkdesk Conversation Orchestrator license, which covers the Studio Connect to Autopilot Voice component in External Voice Stream mode (Talkdesk's article). Talkdesk bills it per minute while the agent holds the call.

1. Create the SIP endpoint

Talkdesk documents only an IP allowlist, so create an endpoint that accepts calls by source address:

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": "Talkdesk",
    "auth": "ip_allowlist",
    "allowed_source_cidrs": ["TALKDESK_SIGNALLING_RANGE_1", "TALKDESK_SIGNALLING_RANGE_2"],
    "srtp": "optional"
  }'

Talkdesk's article says it sends audio over SRTP, and "srtp": "optional" answers SRTP when Talkdesk offers it. The article doesn't say whether Talkdesk requires SRTP; if Talkdesk tells you it does, set srtp to required, which refuses calls without it.

Get Talkdesk's SIP signalling ranges from Talkdesk. Each must be a public IPv4 range of /16 or narrower (IPv6 /48 or narrower). See Platforms that authenticate by source IP. Talkdesk sends SIP from Twilio's network, whose addresses every Twilio customer shares, so the endpoint's address is what keeps other callers out: don't publish it. Keep the response's sip_uri, for example sip:agent-12-jhxmginwjx@sip.thunderphone.com.

2. Send calls with context

In your Studio flow, add Connect to Autopilot Voice in External Voice Stream mode and set its target to the endpoint's sip_uri with ;transport=tls added, for example sip:agent-12-jhxmginwjx@sip.thunderphone.com;transport=tls. The endpoint refuses calls over UDP, which Twilio's SIP uses unless told otherwise.

Talkdesk sends:

  • X-Talkdesk-Interaction-Id, stored as the call's external_call_id;
  • User-to-User, hex-encoded, such as business_hours=open. It reaches the prompt decoded, as {{sip_uui}}.

Version 2.1 of the component can also send Defined headers. Talkdesk's preferences page describes them as JSON sent over a WebSocket, so confirm with Talkdesk whether they arrive as SIP headers before you rely on them.

3. Get the call back

The agent escalates with a REFER to Talkdesk's escalation address, with the hand-off id as hex UUI inside that address, the only place Talkdesk reads it. Add this transfer number (see Add the transfer number and Headers inside the transfer address):

{
  "name": "Talkdesk escalation",
  "number": "sip:escalation@talkdesk.com",
  "headers": {"User-to-User": "autopilot_result={{handoff_id}}"},
  "headers_in_uri": true,
  "uui_encoding": "hex"
}

The address is the one in Talkdesk's article. Version 2.1 of the component reads autopilot_result=; version 1.7 reads escalate_to=, so use that key on 1.7. The REFER looks like this:

Refer-To: <sip:escalation@talkdesk.com?User-to-User=6175746F70696C6F745F726573756C743D...%3Bencoding%3Dhex>

Talkdesk puts the value in a Studio variable. To get the summary and intent, add an Execute Action step on a custom integration built with Connections:

  • Auth type API key, header name Authorization, value Bearer sk_live_….
  • Request: GET https://api.thunderphone.com/v1/calls/handoff?handoff_id= followed by the id from the variable. You can also look the call up by external_call_id with the interaction id.
  • Route on handoff.intent, and show handoff.summary to the person who takes the call.

See Look up a handed-off call.

Test it

Start a call through the Studio flow, ask the agent for a person, and check that the flow continues past the component with the hand-off id in its variable. Then open the call with GET /v1/calls/{call_id}: external_call_id should be the Talkdesk interaction id.

Limits

  • Talkdesk reads at most 256 bytes of UUI and doesn't allow values separated by | or ;, so send a single value. The hand-off id fits.
  • Talkdesk's APIs can't read the agent's transcript. Use the hand-off lookup or GET /v1/calls/{call_id} instead.