Private Branch Exchange REST API Reference
Use the Private Branch Exchange (PBX) REST API to link your PBX system with Alexa-enabled devices on your Alexa Smart Properties (ASP) property. You can use the PBX API to set up Session Initiation Protocol (SIP) trunk connectivity between your ASP units, such as rooms, and extensions on your PBX.
For steps to configure your PBX system to work with Alexa-enabled devices in rooms on a property, see Link a Private Branch Exchange (PBX) to Alexa Smart Properties. For details about PBX systems, see Private branch exchange.
API endpoint
The endpoint of the PBX API is https://api.amazonalexa.com
.
Authentication
Each API request must have an authorization header whose value is the access token retrieved from Login with Amazon (LWA). For details, see Manage API Access.
Access to the PBX API is based on the permission scopes enabled for your skill and granted by the customer. Include the following permission scope when you request an access token.
Permission scope | Description |
---|---|
|
Allows your skill to access the PBX API. |
Operations
The PBX API supports the following types of operations:
- SIP trunk management – Configure SIP trunks to use for calling between Alexa-enabled devices and between Alexa-enabled devices and PBX phones.
- Extension management – Configure extensions for units to be used on the PBX.
SIP trunk management
Operation | HTTP method and URI |
---|---|
| |
| |
| |
| |
|
Extension management
Operation | HTTP method and URI |
---|---|
| |
| |
| |
| |
|
Create SIP trunk
Create trunk connectivity between Alexa and your PBX. You can specify IP-based peers or Fully Qualified Domain Name (FQDN)-based peers.
If you use IP-based peers, the request URI for calls that start from Alexa-enabled devices use IP addresses as the SIP domain. If you use FQDN peers, the request URI for calls that start from Alexa-enabled devices use FQDNs as the SIP domain. You can use either IP-based peers or FQDN-based peers, but not both at the same time.
This operation is asynchronous. Use Get SIP trunk to determine the progress of the creation.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To create a SIP trunk, you make a POST
request to the /v1/communications/network/siptrunk
resource.
Request path and header example
POST /v1/communications/network/siptrunk HTTP/1.1
Host: api.amazonalexa.com
Content-type: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
Request body properties
In the request body, include peers
for IP-based configurations and peer
for FQDN-based configurations. You must include peers
or peer
, but not both. Mixed configurations aren't supported.
Property | Description | Type | Required |
---|---|---|---|
|
Information about your Transport Layer Security (TLS) configuration. |
Object |
No |
|
List of Privacy Enhanced Mail (PEM)-encoded certificate chains. Each certificate chain should contain the standard PEM header and footer. You can include multiple certificates to form a chain for the certificate. You can define multiple certificates to support certificate rotation. |
Array of strings |
Yes |
|
Common Name (CN) or Subject Alternative Name (SAN) of the certificate. Used for certificate validation only. |
String |
Yes |
|
List of peers for IP-based peer configuration. |
Array of objects |
No |
|
IP address of the peer. You can define multiple addresses for high availability. |
String |
Yes |
|
Port number to use to connect to the peer. |
Integer |
Yes |
|
FQDN-based peer configuration. |
Object |
No |
|
DNS Service Locator (SRV) record for the peer. If defined, the system attempts SRV record-based routing. |
String |
Yes |
|
Port number to use to connect to the peer. |
Integer |
Yes |
Response
A successful response returns HTTP 201 Created
, along with trunk information.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
PROVISIONING
and later fails, reach out to your Alexa Smart Properties solution architect with your trunk details.Response body example
{
"trunkId": "amzn1.alexa.network.siptrunk.1",
"status": "PROVISIONING",
"endpoint": "1.siptrunk.prod.amcs-tachyon.com",
"operationId": "dfwqewqre342342"
}
Response body properties
Property | Description | Type |
---|---|---|
|
Unique identifier of the created SIP trunk. |
String |
|
Provisioning status of the trunk. |
String |
|
DNS name or IP address of the endpoint. Enter this value in your SIP trunk configuration for your PBX system. Depending on the underlying signaling implementation, this value might not be present during the |
String |
|
Unique identifier for the SIP trunk creation operation. Use this value to reference the provisioning status. |
String |
HTTP status codes
Status | Description |
---|---|
|
SIP trunk successfully created and awaiting provisioning. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Delete SIP trunk
Delete the specified SIP trunk.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To delete a SIP trunk, you make a DELETE
request to the /v1/communications/network/siptrunk/{trunkId}
resource.
Request path and header example
DELETE /v1/communications/network/siptrunk/{trunkId} HTTP/1.1
Host: api.amazonalexa.com
Content-type: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Unique identifier of the SIP trunk for deletion. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful response returns HTTP 200 OK
, along with the status of the deletion.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
Unique identifier of the deleted SIP trunk. |
String |
|
Provisioning status of the trunk. |
String |
|
Unique identifier that you use to reference the deletion status. |
String |
HTTP status codes
Status | Description |
---|---|
|
Trunk deleted successfully. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
The specified |
|
A conflict exists with the operation on the specified |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Get SIP trunk status
Get the status of SIP trunk creation or update. After you start a Create SIP trunk operation, it takes five to ten minutes for a SIP trunk to be active.
A successful response has the status as ACTIVE
.
PROVISIONING
or switched to ERROR
after ten minutes, contact your Alexa Smart Properties solution architect with your SIP trunk details.This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To get the status of a specific SIP trunk, you make a GET
request to the /v1/communications/network/siptrunk/{trunkId}
resource.
Request path and header example
GET /v1/communications/network/siptrunk/{trunkId} HTTP/1.1
Host: api.amazonalexa.com
Content-type: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Header |
Login with Amazon (LWA) token. For details, see Get an Access Token for SMAPI. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful response returns HTTP 200 OK
, along with the status and configuration of the specified SIP trunk.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
Unique identifier of the SIP trunk. |
String |
|
Provisioning status of the trunk. |
String |
|
DNS name of the endpoint. Depending on the underlying signaling implementation, this value might not be present during |
String |
|
Information about the SIP trunk. |
Object |
|
(Optional) Information about the TLS configuration. |
Object |
|
List of PEM-encoded certificate chains. |
Array of strings |
|
CN or SAN of the certificate. |
String |
|
(Optional) List of peers for IP-based peer configuration. |
Array of objects |
|
IP address of the peer. |
String |
|
Port number to use to connect to the peer. |
Integer |
|
(Optional) FQDN-based peer configuration. |
Object |
|
DNS record for the peer. |
String |
|
Port number to use to connect to the peer. |
Integer |
HTTP status codes
Status | Description |
---|---|
|
Response body contains the trunk configuration. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
The specified |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
List SIP trunks
List the SIP trunks associated with your account.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To get a list of SIP trunks, you make a GET
request to the /v1/communications/network/siptrunk
resource.
Request path and header example
GET /v1/communications/network/siptrunk?maxResults={maxResults}&nextToken={nextToken} HTTP/1.1
Host: api.amazonalexa.com
Content-type: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Query |
Maximum number of results to return in the response. |
Integer |
No |
|
Query |
Token from the previous response. |
String |
No |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful response returns HTTP 200 OK
, along with the list of SIP trunks assigned to your account.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
List of SIP trunks. |
Array of objects |
|
Trunk ID. |
String |
|
DNS name for the endpoint. |
String |
|
Provisioning status of the trunk. |
String |
|
Indicates whether there are more results to return. |
Object |
|
Total number of trunks associated with the account. |
Integer |
|
Included when the response is truncated. Use this value in a subsequent request. |
String |
HTTP status codes
Status | Description |
---|---|
|
Response body contains the list of trunks associated with your account. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Update SIP trunk
Update the configuration for the specified SIP trunk. To update the trunk configuration, you include the same properties that you used to create the configuration.
ACTIVE
state.This operation is asynchronous. Use Get SIP trunk to determine the progress of the update.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To update a SIP trunk, you make a PUT
request to the /v1/communications/network/siptrunk/{trunkId}
resource.
Request path and header example
PUT /v1/communications/network/siptrunk/{trunkId} HTTP/1.1
Host: api.amazonalexa.com
Content-type: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
Request body properties
Property | Description | Type | Required |
---|---|---|---|
|
Information about your Transport Layer Security (TLS) configuration. |
Object |
No |
|
List of Privacy Enhanced Mail (PEM)-encoded certificate chains. Each certificate chain should contain the standard PEM header and footer. Each item might contain multiple certificates, and therefore form a chain for the certificate. You can define multiple certificates to support certificate rotation. |
Array of strings |
Yes |
|
Common Name (CN) or Subject Alternative Name (SAN) of the certificate used for certificate validation. |
String |
Yes |
|
List of peers for IP-based peer configuration. |
Array of objects |
No |
|
IP address of the peer. You can define multiple addresses for high availability. |
String |
Yes |
|
Port number to use to connect to the peer. |
Integer |
Yes |
|
FQDN-based peer configuration. |
Object |
No |
|
DNS Service Locator (SRV) record for the peer. If defined, the system attempts routing by using SRV records. |
String |
Yes |
|
Port number to use to connect to the peer. |
Integer |
Yes |
Response
A successful response returns HTTP 200 OK
, along with trunk information.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
Unique identifier of the SIP trunk. |
String |
|
Provisioning status of the trunk. |
String |
|
Unique identifier that you use to reference the operation status. |
String |
HTTP status codes
Status | Description |
---|---|
|
Response body includes the status of the update. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
The specified |
|
A conflict exists with the operation on the specified |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Delete extension mapping
Delete the mapping between an extension on your PBX and a unit on your property. Make sure to delete the mapping before you delete the unit.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To delete an extension mapping, you make a DELETE
request to the /v1/communications/network/siptrunk/{trunkId}/extension/{extension}
resource.
Request path and header example
DELETE /v1/communications/network/siptrunk/{trunkId}/extension/{extension} HTTP/1.1
Host: api.amazonalexa.com
Accept: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Path |
Internal extension number for the unit. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful response returns HTTP 200 OK
.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
The response has no body.
Response body properties
The response has no body.
HTTP status codes
Status | Description |
---|---|
|
Mapping deleted successfully. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Get extension mapping
Get the mapping between the specified extension on your PBX and a unit on your property.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To get the mapping, you make a GET
request to the /v1/communications/network/siptrunk/{trunkId}/extension/{extension}
resource.
Request path and header example
GET /v1/communications/network/siptrunk/{trunkId}/extension/{extension} HTTP/1.1
Host: api.amazonalexa.com
Accept: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Path |
Internal extension number for the unit. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful creation response returns HTTP 200 OK
, along with details about the specified mapping.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
Type of |
String |
|
Profile ID for the unit attached to the mapping. |
String |
HTTP status codes
Status | Description |
---|---|
|
Response body contains the details of the mapping. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
List extensions in batch
Get the mappings between extensions on your PBX and Alexa-enabled devices in units on your property.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To retrieve extension mappings, you make a GET
request to the /v1/communications/network/siptrunk/{trunkId}/extensions
resource.
Request path and header example
GET /v1/communications/network/siptrunk/{trunkId}/extensions?maxResults={maxResults}&nextToken={nextToken} HTTP/1.1
Host: api.amazonalexa.com
Accept: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Query |
Maximum number of results to return in the response. |
Integer |
No |
|
Query |
Token from the previous response. |
String |
No |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
The request has no body.
Request body properties
The request has no body.
Response
A successful response returns HTTP 200 OK
, along with a list of mappings.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
Response body properties
Property | Description | Type |
---|---|---|
|
List of extension mappings associated with your account. |
Array of objects |
|
Internal extension number for the unit. |
String |
|
Type of |
String |
|
Profile ID for the unit attached to the mapping. |
String |
|
Indicates whether there are more results to return. |
Object |
|
Total number of trunks associated with the account. |
Integer |
|
Included when the response is truncated. Use this value in a subsequent request. |
String |
HTTP status codes
Status | Description |
---|---|
|
Response body includes a list of extension mappings. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Map extension
Create a mapping between an Alexa-enabled device in a unit on your property to an extension on your PBX. If a mapping already exists, this operation updates the mapping.
The mapping uses the communications profile ID for the unit rather than the unit ID. For details about communication profiles, see Manage communication profiles.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To map an extension, you make a POST
request to the /v1/communications/network/siptrunk/{trunkId}/extension/{extension}
resource.
Request path and header example
POST /v1/communications/network/siptrunk/{trunkId}/extension/{extension} HTTP/1.1
Host: api.amazonalexa.com
Accept: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Path |
Internal extension number for the unit. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
Request body properties
Property | Description | Type | Required |
---|---|---|---|
|
Type of |
String |
Yes |
|
Profile ID for the unit to attach to the mapping. |
String |
Yes |
Response
A successful creation response returns HTTP 200 OK
.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
The successful response has no body.
Response body properties
The successful response has no body.
HTTP status codes
Status | Description |
---|---|
|
Mapping created successfully. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Update extension mapping
Update an extension mapping with a new unit. The mapping uses the communications profile ID for the unit rather than the unit ID. For details about communication profiles, see Manage communication profiles.
This operation is available in the following countries.
Healthcare | Hospitality | Senior Living | Core |
---|---|---|---|
US |
US |
US |
US |
Request
To update an extension mapping, you make a PUT
request to the /v1/communications/network/siptrunk/{trunkId}/extension/{extension}
resource.
Request path and header example
PUT /v1/communications/network/siptrunk/{trunkId}/extension/{extension} HTTP/1.1
Host: api.amazonalexa.com
Accept: application/json
Authorization: Bearer {access token}
Request path and header parameters
Parameter | Located in | Description | Type | Required |
---|---|---|---|---|
|
Path |
Identifies the SIP trunk. |
String |
Yes |
|
Path |
Internal extension number for the unit. |
String |
Yes |
|
Header |
Access token for the customer. |
String |
Yes |
Request body example
Request body properties
Property | Description | Type | Required |
---|---|---|---|
|
Type of |
String |
Yes |
|
Profile ID for the unit to attach to the mapping. |
String |
Yes |
Response
A successful response returns HTTP 200 OK
.
On error, the response returns the appropriate HTTP status code and includes a response body with an Error object.
Response body example
The response has no body.
Response body properties
The response has no body.
HTTP status codes
Status | Description |
---|---|
|
Mapping updated successfully. |
|
Indicates that one or more properties in the request body aren't valid. |
|
Request didn't include the authorization token, or the included token expired or isn't valid. Or, you don't have access to the resource. |
|
Indicates that the authorization token is valid, but the requested operation isn't allowed. |
|
Requested resource not found. |
|
Permitted rate limit, specified as the number of requests per unit of time, exceeded. You can retry the request by using exponential back-off. |
|
Error occurred on the server. You can retry the request by using exponential back-off. |
|
Server is down for maintenance, overloaded, or otherwise unavailable to handle the incoming request. |
Object definitions
The PBX API defines the following object definitions.
Error object
The Error
object defines the error type and message included in the response when an error occurs.
The following example shows the response body with the error type and message.
{
"type": "BAD_REQUEST",
"message": "The request is malformed or is missing any required parameters."
}
Property | Description | Type |
---|---|---|
|
Type of error that occurred. |
String |
|
Human-readable error message. The error message appears only for debugging and logging purposes. You must not share it with the customer. No business logic should depend on the content of the error message. |
String |
Related topics
- Link a Private Branch Exchange (PBX) to Alexa Smart Properties
- Private Branch Exchange
- About Alexa Smart Properties
Last updated: Nov 25, 2024