Items marked preview in this article are currently in preview. This preview is provided without a service-level agreement, and Microsoft doesn’t recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Prerequisites
- A saved voice-first agent in a Foundry project that passes browser testing. See Quickstart: Create a voice-first prompt agent.
- Foundry User role on the project, to create and manage telephony bindings.
The Foundry RBAC roles were recently renamed. Foundry User, Foundry Owner, Foundry Account Owner, and Foundry Project Manager were previously named Azure AI User, Azure AI Owner, Azure AI Account Owner, and Azure AI Project Manager. You might still see the previous names in some places while the rename rolls out. The role IDs and core permissions are unchanged by the rename.
- Permission to update the agent and its channels, manage project connections, and create or update telephony bindings.
Teams Phone extensibility prerequisites
For the Teams Phone extensibility path, you need:- A Teams Phone service number assigned to a resource account. See Get Microsoft Teams Calling Plan phone numbers for your tenant.
- The setup in Prepare Teams Phone extensibility, completed with a Teams or Microsoft 365 administrator.
- Access to the selected Azure Communication Services resource.
- For inbound calls, Event Grid write permission on that resource.
- Help from a tenant administrator when secure webhook setup requires Microsoft Entra application or app-role changes.
Twilio prerequisites
For the Twilio path, you need:- A Twilio account with at least one active, voice-capable phone number for inbound calls.
- A Twilio project connection, or the Account SID and Primary Auth Token to create one.
Compare the channel integrations
Choose the provider that owns your number.
The Twilio option appears only in supported public-cloud environments.
Understand the call path
The channel integration determines how an inbound call reaches the agent.- A caller dials the Teams phone number.
- Teams routes the call to your resource account.
- The resource account routes the call to your Communication Services resource.
- Communication Services raises a
Microsoft.Communication.IncomingCallevent through Event Grid to your agent’s telephony callback endpoint. - Foundry matches the callee to a telephony binding, answers the call on your Communication Services resource, and streams the audio to the agent.
Prepare Teams Phone extensibility
A Teams or Microsoft 365 administrator usually completes these steps. Skip this section for Twilio.- Follow Teams Phone System extensibility quick start to provision the application, bot, resource account, and Azure Communication Services association.
- Create or select the Azure Communication Services resource that receives calls for the resource account.
- Create the Teams resource account with the Phone Extensibility application ID.
- Associate the resource account with the Azure Communication Services resource, and synchronize the resource account.
- Acquire a Teams service number and assign it to the resource account. The number can use Calling Plan, Operator Connect, or Direct Routing according to your Teams telephony configuration.
- Assign the Microsoft Teams Phone Resource Account license when required.
- Provide Azure Communication Services server consent for the exact tenant and resource-account object ID.
- For inbound calls, place a controlled call and confirm that Azure Communication Services emits
Microsoft.Communication.IncomingCall.
Set up your preferred interface
Choose Foundry portal, Python SDK, or REST. The Python examples share a client and variables across sections.- Foundry portal
- Python SDK
- REST
Open your project in the Foundry portal. You don’t need the Python packages or a manually acquired bearer token for the portal steps.
Configure a provider connection
Use a project connection for your provider. The portal number setup flow can create it for you. For SDK or REST requests, create or select the connection first.Create a connection to Communication Services
For Teams, use the categoryAzureCommunicationServices. Set target to the resource’s HTTPS endpoint, such as https://<resource-name>.communication.azure.com, not its Azure resource ID. Store the matching resource ID in ResourceId metadata.
Choose an authentication type supported by the connection:
For a managed identity or service principal, grant the required Communication Services permissions before creating a binding or placing calls.
Configure the Twilio project connection
For Twilio, use these settings:
Use the connection’s name as
connection_name in binding and outbound requests. Don’t include provider credentials in those requests.
Understand telephony bindings
A binding routes inbound calls to one agent. You don’t need a binding for outbound call jobs.
Create and list bindings at
{projectEndpoint}/agents/{agentName}/telephony/bindings. Append /{bindingId} to read, update, or delete one. Use the latest ETag for conditional updates and deletion.
Creating a Twilio binding updates the number’s voice URL and status callback, replacing its existing inbound voice routing. Use a number you want to route to this agent.
- Foundry portal
- Python SDK
- REST
Connect a number in the Foundry portal
The portal provides separate setup flows for Teams Phone extensibility and Twilio. Select Microsoft Teams for the Teams Phone extensibility flow.Open the phone-number channel
- In Foundry, open Build > Agents.
- Select the voice-based agent.
- Open Channels.
- In Phone numbers, select Add a number.
- Select Microsoft Teams or Twilio.
Connect a Microsoft Teams number
The Teams Phone extensibility flow creates or updates the Azure Communication Services project connection and telephony binding. Depending on the secure-delivery option, Foundry can also configure the webhook application and IncomingCall Event Grid subscription.Choose secure incoming-call delivery
When Secure incoming-call delivery is shown, choose the approved mode.Under Manual configuration, choose the option that matches your setup:
- Use a customer-managed app registration and let Foundry configure Event Grid: Use a dedicated single-tenant application that you own, or ask an administrator to complete the changes.
- Event Grid and app registration are already configured: Use only when authenticated Event Grid delivery to the exact Foundry webhook is complete. Foundry skips that bootstrap work.
- Select an eligible single-tenant app registration.
- Enter any governance reference required by your organization.
- If the application isn’t listed, confirm that you’re an owner and refresh.
- Ask a tenant administrator to complete required API permissions and app-role assignments.
Select Azure Communication Services
In Azure Communication Services resource, select the resource that receives the calls.If it isn’t listed:- Confirm the tenant and subscription.
- Confirm you can read the resource.
- Confirm the expected resource provider is registered.
- Ask an Azure administrator to correct RBAC.
Enter the Teams number details
Enter the Resource account object ID that the Teams administrator provides. Foundry constructs:Connect a Twilio number
- In Phone numbers, select Add a number > Twilio.
- Select a compatible existing Twilio connection. If none is available, select Create a new Twilio connection.
- To create a connection, enter:
- A unique Connection name.
- The Twilio Account SID. It starts with
ACand contains 34 characters. - The Twilio Primary Auth Token.
- Select Connect or Continue.
- Select one or more voice-capable phone numbers discovered from the Twilio account. You can’t select numbers without the Voice capability.
- Select Continue.
- Review the agent, connection, masked Account SID, and selected numbers.
- Optionally change the display label for each number.
- Select Add selected numbers.
- Review the result for each number. Retry any number that has a failed or unconfirmed result.
- Select Done after all binding operations finish.
Manage a connected number
The Phone numbers card shows each connected number, its optional label, and its provider.- Open the number’s actions menu.
- Select View details.
- Select Edit if the binding supports updates.
- For Microsoft Teams, update the displayed phone number or label. The resource-account object ID and connection are read-only.
- For Twilio, update the label. The phone number and connection are read-only.
- Select Save.
Binding update rules
Setstatus to active to accept new inbound calls again. Both providers support updates to status and label.
Teams bindings also support changes to connection_name and the display phone_number. The provider and resource-account object ID are immutable. For Twilio, delete and recreate the binding to change its phone number or connection.
Register the Event Grid subscription
This section applies only to Teams inbound calls, not Twilio or outbound-only setup. Create an Event Grid subscription on the Communication Services resource that targets the binding’sincoming_call_url. If the portal already configured secure delivery, don’t create a duplicate subscription.
Before running the Bash example, sign in with az login and set these variables:
Complete the application and role setup in Deliver events to Microsoft Entra protected endpoints first. Obtain the webhook tenant and audience from the administrator who configures secure incoming-call delivery. The webhook application identifies the token audience; it isn’t the Microsoft Event Grid first-party application.
Place outbound calls by using the API
Create an outbound call job to call a phone number through a project connection. Creating a call job doesn’t change inbound routing. Complete Set up your preferred interface before running the Python or REST examples. Use a destination you have permission to call. Create or select the provider connection, but skip the inbound binding and Event Grid procedures for outbound-only use.Set the outbound caller and destination
The connection category selects the provider. Use these required settings:
Supply a connection name, not a resource ID or URL. Don’t send
provider, telephony_binding_id, or the legacy connection field in an outbound request.
Generate an idempotency key of 1 to 256 characters for each new call intent. Reuse it with an equivalent request when retrying an uncertain response. The service returns the same job; reusing the key with a different request returns 409 Conflict.
Creation returns 202 Accepted with the job’s id, ETag, Location, and Retry-After in seconds. Acceptance doesn’t mean the recipient answered or the call completed.
The service resolves the latest saved agent definition for each attempt. Provide any required agent inputs in structured_inputs.
- Foundry portal
- Python SDK
- REST
This section covers outbound calls through the API. Select Python SDK or REST to create, read, or cancel a call job. You can use a project connection created in the portal without creating an inbound binding.
Interpret the job status
Inspectstatus, attempt_count, and terminal_reason. Terminal statuses are completed, blocked, expired, failed, and cancelled. Interpret the reason with the status: a queued job can retain a temporary dispatch-deferral reason.
Cancellation returns 202 Accepted while pending, or 200 OK when the job is terminal. Continue reading the job until it reaches a terminal status. Cancellation doesn’t hang up a connected call; a cancellation request after connection can return 409 Conflict.
A job ID isn’t a live call ID. Don’t pass it to /telephony/calls/{callId}.
Optional outbound settings
Use these settings in the Python request model or REST JSON body. The SDK converts Python date and duration objects to the REST wire format.
For Python, use
TelephonyCallJobSchedule and TelephonyOutboundFixedIntervalRetryPolicy to construct these optional values.
Configure transfer to a person
An agent that can’t complete a request should reach a human rather than end the call. Configure named transfer targets for the agent. These targets are separate from its telephony bindings. The examples use PSTN targets, which work with either provider. Use destinations approved for your call flow.- Foundry portal
- Python SDK
- REST
Select Python SDK or REST for the transfer-target configuration examples.
There’s no
twilio destination kind. For Python, use PSTNTelephonyTransferDestination, TeamsTelephonyTransferDestination, or SipTelephonyTransferDestination for the corresponding destination.
Give each target a description that says when to use it. The agent chooses based on that text.
Transfer requests select a target from the agent’s configured list rather than supplying an arbitrary destination.
Manage a live call
These operations list and manage inbound calls. Use a live call ID, not an outbound job ID. Complete Set up your preferred interface before running the examples.- Foundry portal
- Python SDK
- REST
Select Python SDK or REST to list calls or send a transfer or end-call request.
Configure audio for phone calls
Phone networks carry narrowband audio, so tune the agent for the channel:- Set
noise_reduction.typetoazure_deep_noise_suppressionfor contact center traffic. - Increase
silence_duration_ms. Callers on a phone pause more than callers at a keyboard. - Add
phrase_listhints for the identifiers callers read aloud, such as order or policy numbers. - Attach the
end_conversationsystem tool so the agent can end a completed call.
Test the call
- Wait for the selected provider and binding changes to propagate. For Microsoft Teams, also allow time for Azure Communication Services and Event Grid propagation.
- From a controlled caller, call the configured number.
- Confirm the agent answers.
- Complete a short conversation.
- Interrupt the agent.
- Use one safe tool or knowledge path.
- Test the approved human-handoff behavior.
- End the call.
- Confirm that monitoring and trace data appear.
- Test timestamp and time zone.
- Called number.
- Callee identifier.
- Telephony provider and provider call ID, such as an Azure Communication Services correlation ID or Twilio Call SID.
- Agent name and version.
- For Microsoft Teams, the Azure Communication Services resource ID and Event Grid delivery result.
- For Twilio, the Foundry project connection name.
202 Accepted as proof that the call connected.
Trace phone calls
When a call arrives through telephony, the session’s root trace span records the provider, the provider’s call ID, and the dialed and calling numbers. You can correlate a Foundry session with a record in your telephony provider. Caller and callee phone numbers are personal data. Review who can read your project’s Application Insights resource before you enable content capture. See Voice agent tracing, monitoring, and evaluation.Troubleshoot telephony
Disconnect a number
Remove the inbound mapping when you no longer want the number to route calls to this agent. Outbound jobs don’t require a binding; cancel any unwanted jobs separately.- Foundry portal
- Python SDK
- REST
- Open the agent Channels tab.
- In Phone numbers, open the number’s actions menu.
- Select Disconnect number.
- Confirm.
- Release the Teams or Twilio number.
- Remove the Teams resource account.
- Delete Azure Communication Services.
- Remove the bot or app registration.
- Revoke Teams Phone extensibility consent.
- Delete the Twilio account or the Foundry project connection.
Security checklist
- Use Microsoft Entra authentication for Foundry API requests. Prefer managed identity for the Azure Communication Services connection.
- Don’t share Azure Communication Services keys, connection strings, tokens, bot secrets, or portal cookies.
- Store the Twilio Auth Token in the project connection. If it’s exposed, rotate it and update the connection.
- Confirm that the Twilio account owns each inbound number and authorizes each outbound caller number.
- For Teams inbound calls, validate that the Event Grid topic is the intended Azure Communication Services resource.
- Use the exact public Foundry project webhook endpoint.
- Keep webhook audience and Event Grid delivery identity concepts separate.
- Use a dedicated single-tenant webhook application when governance requires it.
- Don’t persist service-generated call callback or media tokens.
- Confirm the binding target before update or deletion.
- Apply recording, consent, disclosure, retention, and privacy requirements.
- Prevent sensitive caller data from being read aloud or unnecessarily stored.