Azure Communications Gateway Provisioning API
Azure Communications Gateway's Provisioning API for telecommunications operators allows you to provision the details of your customers and the numbers assigned to them into Azure Communications Gateway.
Provisioning customer and number information into Azure Communications Gateway is mandatory when using Azure Communications Gateway for Microsoft Teams Direct Routing and Zoom Phone Cloud Peering It's optional for Operator Connect, but allows you to configure a custom SIP header for billing.
You can't use the Provisioning API for Teams Phone Mobile numbers.
Getting started
Prerequisites
- A tenant with the Azure Communications Gateway application deployed.
- The fully qualified domain name (FQDN) for the Azure Communications Gateway that you would like to send queries to, as displayed on the Overview page for the resource in the Azure portal. The API is available on port 443 of the
provapi
subdomain of this domain (provapi.<base-domain>:443
). - A machine with an IP address that allows access to the API, as configured in an allowlist as part of deploying Azure Communications Gateway.
Authentication and authorization
The Provisioning API uses OAuth 2.0 to control access to resources. The client application must obtain a valid authentication bearer token to access the Provisioning API. The bearer token indicates that the application is authorized for one or more of the scopes (roles) for the Provisioning API. We recommend using the client credentials flow (designed for a server-side process).
The following scopes are available for the Provisioning API:
ProvisioningAPI.Admin
: Ability to invoke any operation across the API.ProvisioningAPI.Read
: Ability to invoke any read (GET) operation across the API.ProvisioningAPI.Write
: Ability to invoke any write (PUT, PATCH) operation across the API.ProvisioningAPI.Delete
: Ability to invoke any delete (DELETE) operation across the API.
To set up a client credentials flow:
- Ensure your application can support the client credentials flow.
When your application requests a token for the Provisioning API, it must use the following fields.
Parameter Condition Description tenant required The directory tenant containing the Azure Communications Gateway, in guid or domain-name form. scope required The scope of authorization against the Azure Communications Gateway resource ID. For the client credentials flow described here, the scope should be https://func-voiceservice-rp-prod-eastuseuap.azurewebsites.net/.default
.client_id required The application (client) ID assigned to your app. The
roles
claim in the received token specifies the roles (scopes) that the client application is authorized to access.Requests to the Azure Communications Gateway Provisioning Platform must have an
Authorization
header with this bearer token.See the client credentials flow documentation for examples of using tokens.
- Use the Azure portal to register the application in the same tenant as your Azure Communications Gateway deployment. See Quickstart: Register an app in the Microsoft identity platform - Microsoft Entra | Microsoft Learn.
- Assign yourself as an owner for the app registration. See Assign application owner.
- Configure the app registration created by registering the application with app roles that use the scopes for the Provisioning API, as described earlier.
- See Assign app roles to applications.
- The API for which you need to assign permissions is
AzureCommunicationsGateway
, listed under APIs my organization uses.
- As an administrator for the tenant, allow the application to use the app roles that you assigned. See Grant admin consent.
The Provisioning API uses standard Microsoft chains of trust for security certificates.
Key concepts
The Azure Communications Gateway Provisioning Platform allows you to provision numbers for use with services like Microsoft Teams Direct Routing or Zoom Provider Exchange. The Provisioning Platform has two key resources that you can control: accounts and numbers.
- Account resources are descriptions of your customers (typically, an enterprise), and per-customer settings for service provisioning.
- Number resources belong to an account. They describe telephone numbers (TNs), the services that the numbers make use of (for example, Microsoft Teams Direct Routing), and any extra per-number configuration.
For example, to provide Microsoft Teams Direct Routing service to a customer, Contoso, create an account resource with the Provisioning API for Contoso. The account contains configuration for Direct Routing (for example, a subdomain and corresponding tokens, needed to set up DNS records that Microsoft Teams can use to validate the customer's configuration). You must then add number resources to the account, and enable each number for Direct Routing. Zoom Phone Cloud Peering also requires account and number resources, but Zoom accounts don't contain the same configuration for subdomain and corresponding tokens.
Important
You must enable service on both the account and numbers within the account.
Examples
The following examples show sample requests for creating and managing accounts and numbers.
Create an account to represent a customer
Use PUT on the accounts/<accountName>
endpoint to create an account named contoso
for the customer Contoso and configure one or more communications services for the account. Use an If-None-Match header to verify that an account resource with this name doesn't already exist.
In the following example:
- Direct Routing is configured.
- Caller ID screening is enabled (the default).
- The subdomain for the customer is
contoso
. - The customer-provided DNS TXT values needed to set up DNS records are in the
region1Token
andregion2Token
fields.
Request:
PUT /accounts/contoso?api-version=2023-10-01 HTTP/1.1
If-None-Match: *
Content-Type: application/json
{
"directRouting": {
"callScreening": true,
"subdomain": "contoso",
"subdomainTokens": {
"region1Token": "exampleToken1",
"region2Token": "exampleToken2"
}
}
}
Response:
HTTP/1.1 201 Created
{
"name": "contoso",
"details": {
"directRouting": {
"callScreening": true,
"subdomain": "contoso",
"subdomainTokens": {
"region1Token": "exampleToken1",
"region2Token": "exampleToken2"
}
}
},
"etag": "\"0000241f-0000-0700-0000-650845140000\""
}
View the details of the account
Use GET on the accounts/<accountName>
endpoint to get the details of the account and check that setting up DNS records for the configured subdomain succeeded (only required for Microsoft Teams Direct Routing). The response includes the following fields:
directRoutingProvisioningState
, representing the state of the DNS records. This field is included when the query parameter?status=true
is specified in the request, and is only relevant for Direct Routing.- All configuration previously set (or the default, if a field wasn't set).
- An ETag representing the current state of the account. You can use the value in an If-Match header on subsequent update requests to ensure you don't overwrite changes made by another API users.
Request:
GET /accounts/contoso?api-version=2023-10-01&status=true HTTP/1.1
Response:
HTTP/1.1 200 OK
ETag: "0000241f-0000-0700-0000-650845140000"
{
"directRoutingProvisioningState": {
"subdomainStatus": "Provisioned"
},
"name": "contoso",
"details": {
"directRouting": {
"callScreening": true,
"subdomain": "contoso",
"subdomainTokens": {
"region1Token": "exampleToken1",
"region2Token": "exampleToken2"
}
}
},
"etag": "\"0000241f-0000-0700-0000-650845140000\""
}
Update the configuration for the account
Use PUT on the accounts/<accountName>
endpoint to update the configuration for the account. To ensure that the update doesn't overwrite a change made by another user, add an If-Match header with the ETag from the most recent response for the account.
Request:
PUT /accounts/contoso?api-version=2023-10-01 HTTP/1.1
If-Match: "0000241f-0000-0700-0000-650845140000"
Content-Type: application/json
{
"directRouting": {
"callScreening": false,
"subdomain": "contoso",
"subdomainTokens": {
"region1Token": "exampleTokenNew1",
"region2Token": "exampleTokenNew2"
}
}
}
Response:
HTTP/1.1 200 OK
{
"name": "contoso",
"details": {
"directRouting": {
"callScreening": false,
"subdomain": "contoso",
"subdomainTokens": {
"region1Token": "exampleTokenNew1",
"region2Token": "exampleTokenNew2"
}
}
},
"etag": "\"0000351f-0000-0700-0000-65084a810000\""
}
Add one number to the account
Use PUT on the account/<accountName>/numbers/<phoneNumber>
endpoint to add an E.164 number to the account, enable one or more communications services and add any extra configuration. The chosen communications services must also be configured on the account. Use an If-None-Match header to verify that a number resource with this number doesn't already exist.
In the following example:
- The number is +123451.
- Direct Routing is enabled.
customSipHeader
specifies that Azure Communications Gateway should add a header with the valueexampleHeaderContents
to messages sent to your network.
Important
The name of the custom header is set in the Azure portal configuration for the Provisioning API. It is the same for all messages.
PUT /account/contoso/numbers/%2B123451?api-version=2023-10-01 HTTP/1.1
If-None-Match: *
Content-Type: application/json
{
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
}
Response:
HTTP/1.1 201 Created
{
"phoneNumber": "+123451",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
},
"etag": "\"19004107-0000-0700-0000-65084ad60000\""
}
Update configuration for a number
Use PUT on the account/<accountName>/numbers/<phoneNumber>
endpoint to update configuration for a number. To ensure that the update doesn't overwrite a change made by another user, add an If-Match header with the ETag from the most recent response for the number.
Request:
PUT /account/contoso/numbers/%2B123451?api-version=2023-10-01 HTTP/1.1
If-Match: "19004107-0000-0700-0000-65084ad60000"
Content-Type: application/json
{
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleNewHeader"
}
}
Response:
HTTP/1.1 200 OK
{
"phoneNumber": "+123451",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleNewHeader"
}
},
"etag": "\"19007a0a-0000-0700-0000-65084ca00000\""
}
Add or update multiple numbers at once
Use POST on the account/<accountName>/numbers:batch
endpoint to add up to 100 numbers to the account at once. This endpoint can also be used to update numbers in the account. The numbers are added transactionally: if any update fails, all updates fail.
Request:
POST /account/contoso/numbers:batch?api-version=2023-10-01 HTTP/1.1
Content-Type: application/json
{
"numbers": [
{
"phoneNumber": "+123452",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
}
},
{
"phoneNumber": "+123453",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
}
}
]
}
Response:
HTTP/1.1 200 OK
{
"numbers": [
{
"phoneNumber": "+123452",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
},
"etag": "\"19002b0c-0000-0700-0000-65084d900000\""
},
{
"phoneNumber": "+123453",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
},
"etag": "\"19002c0c-0000-0700-0000-65084d900000\""
}
]
}
Get all numbers in the account
Use GET on the account/<accountName>/numbers
endpoint to get all numbers in the account with their configuration. Use the skip
and maxpagesize
query parameters to control how the response is paginated. If there are more numbers to be returned, the response will contain a nextLink
field indicating the URL to request to get the next page of results.
Request:
GET /account/contoso/numbers?api-version=2023-10-01&skip=0&maxpagesize=2 HTTP/1.1
Response:
HTTP/1.1 200 OK
{
"value": [
{
"phoneNumber": "+123451",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleNewHeader"
}
},
"etag": "\"19007a0a-0000-0700-0000-65084ca00000\""
},
{
"phoneNumber": "+123452",
"accountName": "contoso",
"details": {
"services": {
"teamsDrEnabled": true,
"teamsOcEnabled": false,
"zoomEnabled": false
},
"configuration": {
"customSipHeader": "exampleHeaderContents"
}
},
"etag": "\"19002b0c-0000-0700-0000-65084d900000\""
}
],
"nextLink": "https://<api-fqdn>/account/contoso/numbers?api-version=2023-10-01&skip=2&maxpagesize=2"
}
Troubleshooting
Teams Direct Routing isn't working for numbers on an account.
- Check the DNS token has been validated by sending a GET on the account with the
?status=true
query parameter, and verify thedirectRoutingProvisioningState
hassubdomainStatus
equal toProvisioned
.
- Check the DNS token has been validated by sending a GET on the account with the
I configured a number to use Direct Routing/Zoom, but it doesn't seem to be working.
- Check that the account is configured to use Direct Routing/Zoom, and that the number has this specific feature enabled.
I can contact the API, but after making multiple requests my connections start timing out.
- The provisioning API is rate limited. See Azure Communications Gateway limits, quotas and restrictions for details. Space out your requests, or use the batch endpoint, to avoid being rate limited. The rate limit will time out eventually, and you'll be able to connect.
Next steps
Start integrating with the Azure Communications Gateway Provisioning API.