This documentation provides information for the APIs related to Talk.
To make use of our APIs, you will need an API key in order to authenticate yourself.
This ID must be present in every request inside a header named X-CM-PRODUCTTOKEN. You can find the API Key for your voice account under API Settings in the Voice Management App (https://cm.com/app/voice-management).
The Voice Account ID must be provided in the URL for every request.
This identifier can be found on the URL of CM.com's platform applications, after the language indicator.
An example:
URL | AccountID https://www.cm.com/en-gb/app/dashboard/00000000-0000-0000-0000-000000000000 | 00000000-0000-0000-0000-000000000000
The API requires the user to take pagination into account when requesting data. This is handled using the Skip and Take parameters in the query string.
Each response will contain the following headers to indicated the requested Skip and Take, and the total amount of data:
Header | Description | Schema |
---|---|---|
X-Cm-Pagination-Skip | Amount of items skipped. | number |
X-Cm-Pagination-Take | Amount of items retrieved. | number |
X-Cm-Pagination-Total | Total items that can be retrieved. | number |
This section describes information regarding SIP Accounts that are linked to your Voice Account.
GET https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
[
{
"guid": "00000000-0000-0000-0000-000000000000",
"createdOn": "2020-01-01T00:00:00",
"customerAccountGuid": "voiceAccountId",
"name": "Test display",
"username": "test_username",
"isActive": true,
"inPrison": false
}
]
GET https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
{
"guid": "00000000-0000-0000-0000-000000000000",
"createdOn": "2020-01-01T00:00:00",
"customerAccountGuid": "voiceAccountId",
"name": "Test display",
"username": "test_username",
"isActive": true,
"inPrison": false
}
GET https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/credentials
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
{
"username": "test_username",
"password": "test_password"
}
GET https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/sipEndpoints
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
[
{
"guid": "00000000-0000-0000-0000-000000000000",
"createdOn": "2020-01-01T00:00:00",
"ipAddress": "1.2.3.4",
"port": 0,
"subnetMask": 32,
"protocol": 2,
"isTrusted": false
}
]
GET https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/config
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
{
"cpsLimit": 1,
"ccLimit": 1,
"alwaysAnonymous": false,
"hasAnonymousOverride": false,
"defaultOutboundCallerId": null,
"restrictionType": "Blacklist",
"setAsymmetricRtp": false,
"primaryTrunkId": null,
"secondaryTrunkId": null,
"blockNonEerToEer": false,
"allowPremium": false,
"requiresDtmf": false,
"requiresCcCli": false,
"requiresSfb": false,
"requiresEarlyMediaOn18X": false,
"requiresAnonymousCalls": false,
"requiresHighLoad": false,
"requiresMobileCli": false,
"requiresNonEerToEerTraffic": false
}
POST https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
201 Created
{
"guid": "00000000-0000-0000-0000-000000000000",
"createdOn": "2020-01-01T00:00:00",
"customerAccountGuid": "voiceAccountId",
"name": "Test display",
"username": "test_username",
"isActive": true,
"config": {
"cpsLimit": 1,
"ccLimit": 1,
"alwaysAnonymous": false,
"hasAnonymousOverride": false,
"defaultOutboundCallerId": null,
"restrictionType": "Blacklist",
"setAsymmetricRtp": false,
"primaryTrunkId": null,
"secondaryTrunkId": null,
"blockNonEerToEer": false,
"allowPremium": false,
"requiresDtmf": false,
"requiresCcCli": false,
"requiresSfb": false,
"requiresEarlyMediaOn18X": false,
"requiresAnonymousCalls": false,
"requiresHighLoad": false,
"requiresMobileCli": false,
"requiresNonEerToEerTraffic": false
}
}
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/enable
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
204 No Content
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/disable
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
204 No Content
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/resetpassword
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
{
"username":"test_username",
"password":"new_password"
}
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/displayname
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
{
"name": "new displayname"
}
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
{
"guid": "00000000-0000-0000-0000-000000000000",
"createdOn": "2020-01-01T00:00:00",
"customerAccountGuid": "voiceAccountId",
"name": "new displayname",
"username": "test_username",
"isActive": true
}
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/sipEndpoints
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
[
{
"ipAddress": "1.2.3.4",
"port": 5060,
"subnetMask": 0,
"protocol": 0,
"isTrusted": true
}
]
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
[
{
"ipAddress": "1.2.3.4",
"port": 5060,
"subnetMask": 0,
"protocol": 0,
"isTrusted": true
}
]
PUT https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/config
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your Voice Account identifier. | string (uuid) |
Path | sipAccountId required |
Your SIP Account identifier. | string (uuid) |
{
"cpsLimit": 1,
"ccLimit": 1,
"alwaysAnonymous": false,
"hasAnonymousOverride": false,
"defaultOutboundCallerId": null,
"restrictionType": "Blacklist",
"setAsymmetricRtp": false,
"primaryTrunkId": null,
"secondaryTrunkId": null,
"blockNonEerToEer": false,
"allowPremium": false,
"requiresDtmf": false,
"requiresCcCli": false,
"requiresSfb": false,
"requiresEarlyMediaOn18X": false,
"requiresAnonymousCalls": false,
"requiresHighLoad": false,
"requiresMobileCli": false,
"requiresNonEerToEerTraffic": false
}
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
200 OK
{
"cpsLimit": 1,
"ccLimit": 1,
"alwaysAnonymous": false,
"hasAnonymousOverride": false,
"defaultOutboundCallerId": null,
"restrictionType": "Blacklist",
"setAsymmetricRtp": false,
"primaryTrunkId": null,
"secondaryTrunkId": null,
"blockNonEerToEer": false,
"allowPremium": false,
"requiresDtmf": false,
"requiresCcCli": false,
"requiresSfb": false,
"requiresEarlyMediaOn18X": false,
"requiresAnonymousCalls": false,
"requiresHighLoad": false,
"requiresMobileCli": false,
"requiresNonEerToEerTraffic": false
}
DELETE https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your voice account identifier. | string (uuid) |
Path | sipAccountId required |
Your sip account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
204 No Content
DELETE https://api.cm.com/voice-sipaccountsapi/v1/{voiceAccountId}/sipAccounts/{sipAccountId}/prison
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your voice account identifier. | string (uuid) |
Path | sipAccountId required |
Your sip account identifier. | string (uuid) |
Header | Description | Schema |
---|---|---|
Content-Type | application/json | - |
204 No Content
This section describes information regarding inbound numbers that are linked to your voice account.
GET https://api.cm.com/inboundnumberapi/v2/{voiceAccountId}/inboundnumbers?skip=0&take=10
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your voice account identifier. | string (uuid) |
Query | skip |
Amount of items to skip. Minimum value is 0. |
number |
Query | take required |
Amount of items to retrieve. Minimum value is 1. |
number |
Header | Description | Schema |
---|---|---|
X-Cm-Pagination-Skip | Amount of items skipped. | number |
X-Cm-Pagination-Take | Amount of items retrieved. | number |
X-Cm-Pagination-Total | Total items that can be retrieved. | number |
Content-Type | application/json | - |
[
{
"Number": string,
"OriginalNumber": string,
"VoiceAccount": {
"CreatedOn": datetime,
"Name": string,
"ProductAccountId": string,
"ExternalId": int,
"ExternalName": string,
"IsActive": boolean,
"IsTest": boolean
},
"Application": {
"Guid": string,
"Name": string,
"IsConfigurable": boolean,
"DisplayCode": int
},
"DistributionGroup": {
"guid": string,
"name": string,
"createdOn": datetime,
"updatedOn": datetime,
"dispatchers": [
],
"inboundRoutes": [
{
"createdOn": datetime,
"phoneNumber": long,
"description": string,
"distributionGroupId": int,
"distributionAlgorithm": int
}
]
},
"Country": {
"Code": string,
"Name": string,
"Prefix": string,
"Zone": string
},
"ValidFrom": datetime,
"ValidTo": datetime?,
"NumberType": string,
"UpdatedOn": datetime,
"Status": {
"Guid": string,
"Name": string
}
}
]
[
{
"Number": "31612345678",
"OriginalNumber": "",
"VoiceAccount": {
"CreatedOn": "2019-01-01T00:00:00",
"Name": "Voice account name",
"ProductAccountId": "00000000-0000-0000-0000-000000000000",
"ExternalId": 1,
"ExternalName": "Voice account external name",
"IsActive": true,
"IsTest": false
},
"Application": {
"Guid": "00000000-0000-0000-0000-000000000000",
"Name": "SIP trunking",
"IsConfigurable": true,
"DisplayCode": 1
},
"DistributionGroup": null,
"Country": {
"Code": "NL",
"Name": "Netherlands",
"Prefix": "31",
"Zone": "EER"
},
"ValidFrom": "2019-01-01T00:00:00",
"ValidTo": null,
"NumberType": "FIXED_LINE",
"UpdatedOn": "2019-01-01T00:00:00",
"Status": {
"Guid": "00000000-0000-0000-0000-000000000000",
"Name": "Operational"
}
}
]
GET https://api.cm.com/inboundnumberapi/v2/{voiceAccountId}/inboundnumbers/export?exportAll=false
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your voice account identifier. | string (uuid) |
Query | exportAll |
Export inbound numbers for all voice accounts within the organization. Default value is false. |
boolean |
Header | Description | Schema |
---|---|---|
X-CM-FILENAME | Name of the generated Excel file. | string |
Content-Type | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | - |
The response body will contain the binary data of the Excel file.
There are a couple of different configurations for phone numbers. This section will explain them in detail.
Name | Description | Required | Schema |
---|---|---|---|
Type | The type should be none | Yes | string |
PhoneNumber | The phone number to configure | Yes | number |
Name | Description | Required | Schema |
---|---|---|---|
Type | The type should be sip | Yes | string |
PhoneNumber | The phone number to configure | Yes | number |
DistributionGroupGuid | The distribution group used for the phone number, find the right Guid using the following endpoint: GET https://api.cm.com/voiceroutingapi/v1/{voiceAccountId}/distributiongroups | Yes | string (uuid) |
Algorithm | RoundRobin (shares all incoming calls over the given IPs) or Failover (looks at the first IP and only if that gives an error, the next one will be tried, etc.) | Yes | string |
AnonymousMode | If 1 is used and a call contains the Privacy:id header, the call will be passed 'as is'. If 2 is used and a call contains the Privacy:id header, all headers containing the callers' phone number will be stripped (P-Asserted-Identity, Remote-Party-ID) and the URI in the From header will be replaced with [email protected] . |
Yes | number |
Name | Description | Required | Schema |
---|---|---|---|
Type | The type should be notification | Yes | string |
PhoneNumber | The phone number to configure | Yes | number |
AppAccountGuid | Find the Guid using the following endpoint: GET https://api.cm.com/voice-appaccountapi/v1/{voiceAccountId}/appaccounts | Yes | string (uuid) |
PromptType | File or TTS (Text To Speech) | Yes | string |
Prompt | The prompt message or the path of the audio file | Yes | string |
Language | Language formatted like 'en-GB' | For TTS | string |
Gender | Voice gender (Male or Female) | For TTS | string |
VoiceNumber | See the voice api docs for all the options https://www.cm.com/en-en/app/docs/voice-api-apps/v2.0 (Text-To-Speech) | For TTS | number |
TimeoutInMilliseconds | The time to let the phone ring at the receiver | No | number |
CallbackUrl | The URL (including http(s)://) for the callback. See https://www.cm.com/en-en/app/docs/voice-api-apps/v2.0 (Notification App callback) for more info. | No | string |
Name | Description | Required | Schema |
---|---|---|---|
Type | The type should be directforwarding | Yes | string |
PhoneNumber | The phone number to configure | Yes | number |
AppAccountGuid | Find the Guid using the following endpoint: GET https://api.cm.com/voice-appaccountapi/v1/{voiceAccountId}/appaccounts | Yes | string (uuid) |
DestinationNumber | The destination number to forward to | Yes | number |
CustomCallerId | Number alias | No | string |
PUT https://api.cm.com/voice-phonenumberapi/v1/{accountId}/phonenumbers
The body contains all numbers you want to update with their desired configuration. It should be an array, see the following example with all the possible configurations:
[
{
"type": string,
"phoneNumber": number
},
{
"type": string,
"phoneNumber": number,
"distributionGroupGuid": string,
"algorithm": string,
"anonymousMode": number
},
{
"type": string,
"phoneNumber": number,
"appAccountGuid": string,
"promptType": string,
"prompt": string,
"language": string,
"gender": string,
"voiceNumber": number,
"timeoutInMilliseconds": number,
"callbackUrl": string
},
{
"type": string,
"phoneNumber": number,
"appAccountGuid": string,
"destinationNumber": number,
"customCallerId": number
}
...
]
It depends on the type of the configuration which items should be additionally added. See the following example body for all the possible configurations
[
{
"type": "none",
"phoneNumber": 31612345678
},
{
"type": "sip",
"phoneNumber": 31612345678,
"distributionGroupGuid": "00000000-0000-0000-0000-000000000000",
"algorithm": "RoundRobin",
"anonymousMode": 1
},
{
"type": "notification",
"phoneNumber": 31612345678,
"appAccountGuid": "00000000-0000-0000-0000-000000000000",
"promptType": "TTS",
"prompt": "examplePrompt",
"language": "en-GB",
"gender": "Male",
"voiceNumber": 1,
"timeoutInMilliseconds": 0,
"callbackUrl": null
},
{
"type": "directforwarding",
"phoneNumber": 31612345678,
"appAccountGuid": "00000000-0000-0000-0000-000000000000",
"destinationNumber": 31687654321,
"customCallerId": null
}
]
The function will return the complete settings of the inserted body without the null values.
[
{
"type": string,
"phoneNumber": number
},
{
"type": string,
"phoneNumber": number,
"distributionGroupGuid": string,
"algorithm": string,
"anonymousMode": number
},
{
"type": string,
"phoneNumber": number,
"appAccountGuid": string,
"promptType": string,
"prompt": string,
"language": string,
"gender": string,
"voiceNumber": number,
"timeoutInMilliseconds": number,
"callbackUrl": string
},
{
"type": string,
"phoneNumber": number,
"appAccountGuid": string,
"destinationNumber": number,
"customCallerId": number
}
...
]
[
{
"type": "none",
"phoneNumber": 31612345678
},
{
"type": "sip",
"phoneNumber": 31612345678,
"distributionGroupGuid": "00000000-0000-0000-0000-000000000000",
"algorithm": "RoundRobin",
"anonymousMode": 1
},
{
"type": "notification",
"phoneNumber": 31612345678,
"appAccountGuid": "00000000-0000-0000-0000-000000000000",
"promptType": "TTS",
"prompt": "examplePrompt",
"language": "en-GB",
"gender": "Male",
"voiceNumber": 1,
"timeoutInMilliseconds": 0
},
{
"type": "directforwarding",
"phoneNumber": 31612345678,
"appAccountGuid": "00000000-0000-0000-0000-000000000000",
"destinationNumber": 31687654321
}
]
The CDR Web API exposes a set of HTTP REST endpoints which allow you to retrieve the Call Detail Records for your voice traffic. It uses JSON as the language of information exchange.
The API uses rate limiting to prevent (accidental) abuse and to safeguard the resources the API accesses. The time limit is set to one request every 5 minutes for each unique request. The uniqueness of a request is determined by the Voice Account ID, From and Skip values.
The API will respond with a 429 Too Many Requests when the same request is sent within 5 minutes. The header Retry-After is added to the response indicating the amount of time (in seconds) left.
Retrieves the conversations for a single voice account.
GET https://api.cm.com/cdrapi/v1/{voiceAccountId}/conversations
Type | Name | Description | Schema |
---|---|---|---|
Path | voiceAccountId required |
Your voice account identifier. | string (uuid) |
Query | skip |
Amount of items to skip. Minimum value is 0. |
number |
Query | take required |
Amount of items to retrieve. Minimum value is 1. |
number |
Query | from required |
The timestamp indicating the start date. | DateTime Supported formats: yyyy-MM-ddTHH:mm:ss yyyy-MM-dd MM-dd-yyyy |
Query | to required |
The timestamp indicating the exclusive end date. Maximum range is 1 week. |
DateTime Supported formats: yyyy-MM-ddTHH:mm:ss yyyy-MM-dd MM-dd-yyyy |
Header | Description | Schema |
---|---|---|
X-Cm-Pagination-Skip | Amount of items being skipped. | number |
X-Cm-Pagination-Take | Amount of items being retrieved. | number |
X-Cm-Pagination-Total | Total items that can be retrieved. | number |
Content-Type | application/json | - |
A successful request will return a JSON array containing the conversation objects.
Name | Type | Description |
---|---|---|
voiceAccountId | GUID | The ID identifying your traffic. |
voiceAccountName | Alphanumeric | The name of your Voice Account. |
externalReference | Alphanumeric | Unique identifier of the call. (if applicable) |
callId | Alphanumeric | The unique Call Id identifing the call. |
startedOn | DateTime UTC | The timestamp the call started. |
answeredOn | DateTime UTC | The timestamp the call was answered. |
finishedOn | DateTime UTC | The timestamp the call was finished. |
durationInSeconds | Numeric | The duration in seconds. |
isAnonymous | Boolean | Whether the call was anonymous. |
direction | Alphanumeric | The direction of the call. |
callerId | Alphanumeric | The phone number identifying the caller. |
calleeId | Alphanumeric | The phone number identifying the callee. |
calleeDestination | Alphanumeric | The callee's destination. |
CalleeDestinationId | Alphanumeric | The callee's destination ID. |
surchargeAmount | Decimal, precision of 4 | The surcharge amount. (if applicable) |
surchargeType | Alphanumeric | Can be either 'Penalty surcharge' or 'Non-EER to EER'. (if applicable) |
surchargeUnitPrice | Decimal, precision of 4 | Surcharge unit price per minute. (if applicable) |
cost | Decimal, precision of 4 | Call cost. |
currency | Alpha | Currency of the call cost. |
unitPrice | Decimal, precision of 4 | Call cost per minute. |
apiAccount | Alphanumeric | API account user name. (if applicable) |
sipAccount | Alphanumeric | SIP account user name. (if applicable) |
customSipAccountName | Alphanumeric | Custom name of the SIP account. (if applicable) |
customResellerPrice | Decimal, precision of 4 | Custom reseller price of the call. (only included for resellers) |
[
{
"voiceAccountId": "17f23fdf-21cd-48cd-bf1d-45012659004f",
"voiceAccountName": "MaxCorp B.V.",
"callId": "f452122c-ec1c-423a-b664-48aa51112a26",
"startedOn": "2018-03-01T07:46:46",
"answeredOn": "2018-03-01T07:46:46",
"finishedOn": "2018-03-01T07:46:56",
"durationInSeconds": 11,
"isAnonymous": false,
"direction": "outbound",
"callerId": "31612345678",
"calleeId": "31612345670",
"calleeDestination": "NETHERLANDS MOBILE VODAFONE",
"surchargeAmount": null,
"surchargeType": null,
"surchargeUnitPrice": null,
"cost": 0.0123
}
]