Call Routing via APIs

Introduction

Suppose you have a Sales representative that's been engaged in conversations with a prospect for the past month for a giant deal. Wouldn't it be great if when the prospect calls back on the company mainline, the call goes directly to the representative instead of sending them through an IVR? Along with showing the prospect that they're being given extra attention, it would also help the sales continue conversations with ease.

Dialpad's Routing APIs allow you to do just that! With these APIs, you can have total control over where each inbound call is routed, whether it's though our standard routing mechanisms in a Department or Call Centre, or whether it's sent through directly to a User. This document describes the basics of call routers, the steps needed to setup these call routers and the expected responses.

How Call Routing Works

960

The above diagram illustrates the working of a call router. Once a router is setup, call information is published to a specified URL. The third party then uses that data to generate routing information for that call. The call is then routed to the appropriate user or department or call centre. In the above example, the call was routed to a user. However, the system is flexible to route calls to a department or call centre depending on the call.

Creating the Call Router

To create a call router, invoke the POST callrouters method.

FieldTypeRequired?Description
namestringtrueSpecify a name for the call router
routing_urlstring (URL)trueThe URL that should be consulted to route calls
secretstringfalseA JWT secret to be used
office_idstringtrueThe office to which the call router belongs
default_target_idstringtrueThe fallback target to be used in case of client server unavailability
default_target_typestringtrueThe type associated with the default_target_id (i.e. office, department, callcenter, or user)
enabledbooleanfalseSet to true as default. If set as false, the call router will act as pass through to the office mainline

e.g.

import requests

url = "https://dialpad.com/api/v2/callrouters"

payload = '''{
  "default_target_id": "123456",
  "default_target_type": "callcenter",
  "name": "Hello Router",
  "office_id": "223456",
  "routing_url": "https://yourroutingservice.com/routecall",
}'''

headers = {
  'accept': "application/json",
  'content-type': "application/json"
}

response = requests.request("POST", url, data=payload, headers=headers)

Upon successful creation of the call router, the following response is sent

{
  “id”: “generated id”,
  “name”: “name”,
  “routing_url”: “routing_url”,
  “office_id”: “office_id”,
  “default_target_id”: “12341234”,
  “default_target_type”: “callcenter”,
  “enabled”: true,
  “phone_numbers”: [“e164 number”, ...],
  “signature”: {
    “type”: “jwt”,
    “algo”: “HS256”,
    “secret”: “secret”
  }
}

To set a phone number for the call router, invoke the POST callrouters/id/assign_number method. This number should be provided to your customers. Please ensure the office has available Additional Number licenses for phone numbers to be assigned.
e.g.

import requests

url = "https://dialpad.com/api/v2/callrouters/323456/assign_number"

headers = {
  'accept': "application/json",
  'content-type': "application/json"
}

response = requests.request("POST", url, headers=headers)

Providing Routing Information to the Call Router

Once a call comes into the number assigned to the call router, a JWT will be POST-ed to the routing_url . The JSON content of the JWT will be of the form:

{
  “date_started”: <ms_since_epoch>,
  “call_id”: <call_id>,
  “external_number”: “<e164 number>”,
  “internal_number”: “<e164 number>”,
  “contact_id”: <contact_id>,
  “contact_type”: <contact_type>,
}

The external_number will contain the number of the caller.

Allowed Actions

Based on the information provided to the URL, you can instruct the call router to take one of three actions. By default the action is assumed to be the route action, so to trigger a different action you must specify the desired action in the action field of the response payload.

FieldTypeRequired?
actionOne of: "route", "ask", "end"false

Route Action

The Route action will route the call to the specified target.

FieldTypeRequired?Description
target_idintegertrueThe ID of the Dialpad target that should receive the call
target_typestringtrueThe type associated with the target_id (i.e. office, department, callcenter, or user)

Ask Action

In some scenarios, the ideal routing behaviour may be more complex than just dynamically forwarding a call. It may be desirable to ask the caller to choose between several options and make additional routing decision based on their response. It may also be desirable to play an audio clip to the caller and end the call (e.g. "Our office is currently closed. Please call back between 9 to 5 on a weekday"). This can be achieved using the ask action.

An ask action will ask the caller a specified question via a synthesized text-to-speech audio clip. The caller will be allowed to enter a response via their number pad. After an ask action is completed, your routing endpoint will receive an additional request to allow it to take an additional action based on the caller's response. That information will be included in the post-ask routing request in the form of a string containing the keys that the caller pressed. The hint_name you provide will be the field in which the caller's response will appear in the post-ask routing request.

FieldTypeRequired?Description
messagestring or arraytrueThe message that should be played to the caller via text-to-speech
*see additional considerations section
hint_namestringtrueThe field name in which to insert the caller's response in the subsequent routing request (more details below)
finish_on_keystringfalseThe key the caller should press to signal that they are finished inputting digits (by default, the input will conclude when the caller has pressed the number of digits specified in num_digits)
num_digitsintegerfalseThe number of digits that the caller should enter (defaults to 99)
valid_digitsstringfalseA string containing all keypad values that the caller can include in their response (defaults to "0123456789*#")
(the default is the full set of possible digits)
retriesintegerfalseThe number of times the audio prompt should be repeated to the caller if they don't press any buttons on their keypad (defaults to 10)
timeoutintegerfalseThe number of seconds to wait for the caller to press a button before repeating the prompt (defaults to 5)

Using ask actions increases the potential complexity of your routing logic, especially if the routing flow contains multiple ask actions. A new request will be hitting the same routing endpoint for every step of the routing flow, which can be logistically challenging. Making good use of the hint_name field can significantly simplify the logistical challenge. If you use a distinct hint_name for each ask action in your routing flow, then you will be able to distinguish between the post-ask requests without needing any information other than the request itself. Choosing human-readable names can also improve debugging by making it easier to read and comprehend a series of routing requests.

For very complex flows, it may even be helpful to break up the routing process into several parts, and handle each part with a different router. For example, one call router could serve as a single entry point for all the calls within a country, and could redirect the calls to region-specific call routers based on the area code of the caller. Since each router can specify its own routing URL, this strategy can be used to turn a single hard-to-understand routing endpoint into several easier-to-understand routing endpoints.

The caller's response to ask actions will only be included in the routing request immediately after that action, rather than being carrying forward into every subsequent routing request for that call. If the message repeats retries times without any response from the caller, the call will simply end, and there will be no subsequent routing request.

End Action

An end action will play a synthesized text-to-speech audio clip and then hang up the call.

FieldTypeRequired?Description
messagestring or arraytrueThe message that should be played to the caller via text-to-speech
*see additional considerations section

Deleting Call Routers

Call routers can be deleted by calling the DELETE callrouters/id method. Note that deletion takes effect immediately and would place the number assigned to the call router in reserve.

Error Handling

If the endpoint takes more than 5 seconds to respond or if there are more than 10 failures in an hour, then the call router will be automatically disabled, and an email will be sent to the office admin. In order to rejuvenate the call router, it must be re-enabled via the PATCH callrouters/id method. In this situation, the first step will be to investigate and correct the underlying issue in your routing endpoint.

Uniform Errors

In many cases the issue will have a consistent source, and the error may be completely resolved once the issue is addressed. In this situation, the call router can simply be re-enabled the call router by setting the enabled property to true via the PATCH endpoint.

Inconsistent Errors

In some situations (such as performance issues that occasionally result in request latency greater than 5-seconds), your routing endpoint may still have occasional routing errors after applying a fix. In this situation, it may be desirable to re-enable the router in addition to resetting the internal error count. To accomplish this, you can make a PATCH request that includes "reset_error_count": true, "enabled": true.

Additional Notes

Text-to-speech

For best results with text-to-speech fields (i.e. the message field), the value should either be a single short string, or an array of short strings. When the Dialpad backend receives an end or ask action, it needs to take the message, synthesize it into an audio file, and then play that audio file to the caller. Text-to-speech is a computationally expensive operation, and in this context it needs to happen as quickly as possible. By allowing the input to be a list of strings, we can process each string into an audio file independently. This means that playback can begin as soon as the first string has been processed, rather than blocking on processing the whole message.

There is also a caching mechanism that helps reduce the playback latency. If Dialpad has seen a particular string before, then it likely already has an audio file in the cache that it can retrieve immediately.

To leverage these mechanisms most effectively:

  • The message should be split into small pieces whenever possible
  • The first string in a list of messages is the most important, since playback cannot begin until that string is processed.
  • If the first string is always the same, Dialpad can make use of the audio file cache, so any dynamic strings should ideally come after an initial static string, where the processing time is much less likely to matter.

Call routers can be assigned multiple numbers.

Using multiple numbers may be useful for assessing the efficacy of an ad campaign or providing separate numbers for support and sales. Your routing endpoint can use this information to make routing decisions, since the internal_number will indicate which number the caller dialed.

Call routers can be configured to send JWT payloads for additional security.

In order to verify that a routing request is genuine, you can set the secret property on the call router by using the POST or PATCH endpoints. If a call router is given a secret, then it will use that secret to send a signed JWT payload to your endpoint, rather than a raw JSON payload.