Open in
Connect from Microsoft Dynamics 365
Send Dynamics 365 Contact Center and Copilot Studio calls to a ThunderPhone agent through your SBC with X-headers, and look up the agent
Dynamics 365 Contact Center sends the caller to the agent through your session border controller (SBC), with up to five X-headers including the conversation id. When the agent is done, it hangs up, your SBC brings the caller back into Dynamics 365, and an HTTP Request node fetches the hand-off.
Before you start
- A ThunderPhone agent and an organization API key.
- The Dynamics 365 Contact Center voice channel, connected through Azure Communication Services Direct Routing to an SBC you run (SBC requirements): a supported SBC with a public certificate, TLS 1.2 on port 5061 and SRTP toward Microsoft.
- SIP X-header support on the Transfer conversation node (Copilot Studio). Confirm it is available in your environment.
Dynamics 365 transfers only to a phone number, and Microsoft authenticates Direct Routing by certificate, not by password. Your SBC sits between Microsoft and ThunderPhone and turns that number into the agent's SIP address.
1. Create the SIP endpoint
The call reaches ThunderPhone from your SBC, so create a standard endpoint for the SBC to use:
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": "Dynamics 365 SBC"}'Store the password from the response straight away; it is shown once, and
your SBC answers ThunderPhone's challenge with it. If your SBC can't do digest
authentication, create the endpoint with auth set to ip_allowlist and your
SBC's public address instead; see
Platforms that authenticate by source IP.
2. Send calls with context
- Pick a phone number for the agent on your SBC, such as
+14155550188. - On the SBC, route calls to that number to the endpoint's
sip_uri, for examplesip:agent-12-jhxmginwjx@sip.thunderphone.com, over TLS on port5061. ThunderPhone finds the endpoint by the user part (agent-12-jhxmginwjx), which must be in both the request URI and theToheader. Pass the X-headers through unchanged. - In Copilot Studio, add a Transfer conversation node with
External phone number transfer to that number, and add the X-headers:
X-Call-ID: the Dynamics 365 conversation id. No Microsoft header carries it, so add it here; ThunderPhone stores it as the call'sexternal_call_id. Confirm in Copilot Studio which variable holds the conversation id.- Up to four more, such as
X-Customer-Tier.
Microsoft sends at most five X-headers, with names up to 64 characters and
values up to 256, using letters, digits and = ; . ! % * _ + ~ -. It writes
the prefix as lowercase x-; ThunderPhone matches header names ignoring case,
so x-customer-tier reaches the prompt as {{sip_x_customer_tier}}.
If you build the call with Azure Communication Services Call Automation
instead, AddSipX writes X-MS-Custom- names by default. Pass
SipHeaderPrefix.X so X-Call-ID keeps its name
(custom context).
3. Get the call back
The agent returns the call: it says goodbye and hangs up. Add this transfer number (see Add the transfer number):
{"name": "Dynamics 365", "action": "return"}Bringing the caller back into Dynamics 365 is your SBC's job. Microsoft
documents one way in for a call with context: a new call through the SBC to a
number registered in Dynamics 365, with UUI whose keys match context variables
you set up under Workstreams → Advanced settings
(third-party IVR transfer).
Work out with your SBC vendor how the caller reaches that number when
ThunderPhone hangs up, and carry the conversation id you sent in X-Call-ID
so the flow can find the call.
Then fetch the hand-off with a Copilot Studio HTTP Request node:
GET https://api.thunderphone.com/v1/calls/handoff?external_call_id=followed by the conversation id.- Header
Authorization: Bearer sk_live_…. - Parse the response into a variable and use
handoff.summaryandhandoff.intent.
See Look up a handed-off call.
Test it
Call a Dynamics 365 number that reaches the transfer node, ask the agent for a
person, and check that the caller comes back into Dynamics 365. Then open the
call with GET /v1/calls/{call_id}: sip_headers should list x-call-id, and
external_call_id should be the conversation id. If the call never reaches the
agent and your SBC logs SIP 404, its request URI or To header doesn't carry
the endpoint's user part.
Limits
- An SBC is required. Microsoft can't dial a SIP address or answer a digest challenge.
- Microsoft sends at most five X-headers, and keeps only the first five on a call coming in. Dynamics 365 takes at most 128 characters of UUI.
- Microsoft doesn't document reading headers on a
BYE, so the hand-off comes back only through the lookup.