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

Contact centers

Connect from Five9

Send Five9 calls to a ThunderPhone agent over SIP with AI Agent Connect, and get them back with routing headers your IVR script reads.

Your Five9 IVR script sends the caller to the agent with Five9's call details. When the agent is done, it hangs up with routing headers on the SIP BYE, which the script reads into call variables to route the caller.

Before you start

  • A ThunderPhone agent and an organization API key.
  • Five9's AI Agent Connect add-on. Five9 limits it to AI providers it has accredited, and Five9's implementation team sets it up: it imports the provider's IVR script template, creates the call variables and points the script's Third Party Transfer module at the provider. ThunderPhone isn't on Five9's accredited list yet: ask your Five9 account team or ThunderPhone support before you plan around it.

1. Create the SIP endpoint

Five9's Third Party Transfer module dials a phone number, not a SIP address, and other providers' Five9 integrations authenticate Five9 by source address rather than a password. So create an ip_allowlist endpoint with the number Five9 will dial as a dial-in number (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": "Five9",
    "auth": "ip_allowlist",
    "allowed_source_cidrs": ["FIVE9_SIGNALLING_RANGE_1", "FIVE9_SIGNALLING_RANGE_2"],
    "dial_in_numbers": ["+14155550188"]
  }'
  • allowed_source_cidrs: the SIP signalling ranges of your Five9 data centers, from Five9. Each must be a public IPv4 range of /16 or narrower (IPv6 /48 or narrower).
  • dial_in_numbers: the number Five9's script will dial, written the way Five9 sends it. It doesn't have to be a real phone number. It can't already be in use on ThunderPhone, as a phone number or on another endpoint: that returns 409.

Five9's addresses are shared by all its customers, so any other Five9 customer who dials the number reaches your agent. Where you choose the number, pick a long one nobody would guess (up to 15 digits), make sure Five9 sends it to ThunderPhone rather than out to the phone network, and don't publish it.

2. Send calls with context

Ask Five9's implementation team to:

  • Send the call from the Third Party Transfer module to sip:+14155550188@sip.thunderphone.com, with the number in both the request URI and the To header. The module takes the number, with the provider's SIP domain in a header.
  • Send it over TLS (port 5061) or TCP (port 5060). The endpoint refuses UDP, and Five9 doesn't publish which transport it uses, so make sure it isn't UDP.
  • Turn on Return After 3rd Party Call, so the script continues when the agent hangs up (Five9 allows up to 3,600 seconds on the third-party call).

Five9's guide lists the values it sends (call.ANI, call.DNIS, call.call_id, call.session_id, call.campaign_name and others), not their header names. Other AI providers' Five9 integrations document them on the wire as X-CallANI, X-CallDNIS, X-CallID, X-CallSessionID, X-CallCampaign and X-AgentID; check them on your first test call. Each reaches the prompt as a variable, such as {{sip_x_callcampaign}}. X-CallID is stored as the call's external_call_id.

3. Get the call back

The agent returns the call: it says goodbye and hangs up, and the BYE carries the four headers Five9's script reads. Add this transfer number (see Add the transfer number):

{
  "name": "Five9 agent",
  "action": "return",
  "headers": {
    "X-RouteType": "SkillTransfer",
    "X-RouteValue": "Support",
    "X-RouteReason": "{{handoff_intent}}",
    "X-CustomMetaData": "handoff_id={{handoff_id}}"
  }
}
  • X-RouteType and X-RouteValue tell the script where to send the caller, here the Support skill. Values other providers document for X-RouteType include SkillTransfer, PhoneTransfer, Hangup and DispositionOnly; agree the values with whoever maintains the script. For several destinations, add one return per destination with a different name and X-RouteValue.
  • X-RouteReason carries the agent's intent label, such as billing_dispute.
  • X-CustomMetaData carries the hand-off id. The BYE also carries it as X-TP-Handoff-Id, which Five9 doesn't read.

Five9's script maps the four headers into call variables. For the agent's summary, have the script call the hand-off lookup with an IVR Query module: GET https://api.thunderphone.com/v1/calls/handoff?external_call_id= followed by call.call_id, with an Authorization Profile that sends Authorization: Bearer and your API key. See Look up a handed-off call.

Test it

Call into the IVR script, ask the agent for a person, and check that the script routes the caller with the call variables filled. If the call never reaches the agent, check that the number in the request URI and To header matches the dial-in number, that Five9's source address is in allowed_source_cidrs, and that the call came over TCP or TLS. Then open the call with GET /v1/calls/{call_id}: sip_headers should list x-callid, and external_call_id should match call.call_id in Five9.

Limits

  • Five9's guide documents routing data on the BYE and doesn't mention accepting a REFER, so the hand-back is a cold transfer by the script.
  • Five9 reads X-RouteType, X-RouteValue, X-RouteReason and X-CustomMetaData, not User-to-User. ThunderPhone sends each header value at most 256 bytes long.
  • Five9 recommends keeping custom headers to about ten to avoid packet fragmentation.