Heartbeat is currently available in Beta
Heartbeat API notifies the ‘health’ of an Exophone in real time based on which actions can be taken at your end. To subscribe to Heartbeat, you need to put a working HTTP URL (it should return 200 OK on POST request) in the Notifications Settings of your Dashboard along with frequency mentioned in minutes. The URL endpoint will receive heartbeat notifications continously at the frequency you set.
Heartbeat is subscribed for all ExoPhones present in your account
This webhook (HTTP Push API) will ping information about your ExoPhone health every nth minute as configured. If some ExoPhones are facing connectivity issues, we will provide details about those ExoPhones alone. You can use the Get ExoPhone Details API described in next section for further connectivity information about an ExoPhone.
HTTP POST
method is used for heartbeat requests and each request will be issued with the Content-Typ
e header application/json
Description of parameters which will be set in heartbeat requests to your endpoint:
Parameter Name |
Description |
timestamp |
This denotes the time when a particular heartbeat request was generated in our system. |
status_type |
This will provide an overall state of all your ExoPhones combined. Possible values
|
incoming_affected |
Array; List of unique SIDs denoting ExoPhone(s) for which incoming call connectivity is affected |
outgoing_affected |
Array; List of unique SIDs denoting ExoPhone(s) for which outgoing call connectivity is affected |
data |
This block contains comma separated nested JSON blocks denoting information per ExoPhone which is having connectivity issues as mentioned in incoming_affected or outgoing_affected array. phone_number_sid (key): Unique string which identifies the ExoPhone owned by you. This may not always be same as your phone number. You can find out your ExoPhone SID by triggering a GET request using your auth credentials on https://api.exotel.com/v2/accounts/<account_sid>/incoming-phone-numbers It’s value will be a nested JSON containing below: phone_number - Denoting the phone_number of the ExoPhone in E.164 format. This can be different than the SID of the phone number. For example, 02030090005 denotes the phone_number_sid (key) and phone_number is present as parameter within it in E.164 format. "02030090005":{
"phone_number": "+912030090005"
}
Note: There could be multiple blocks depending on numbers present in incoming_affected and outgoing_affected list. |
Example webhook payload with possible scenarios:
Scenario #1
If everything is working fine i.e. all ExoPhones are healthy (OK):
{ "timestamp": "2018-08-22T15:19:23Z", "status_type": "OK", "incoming_affected": null, "outgoing_affected": null, "data": {} }
Scenario #2
If some ExoPhones connectivity is affected (WARNING):
{ "timestamp": "2018-08-22T15:19:23Z>", "status_type":"WARNING", "incoming_affected":[ "07930061010" ], "outgoing_affected": null, "data":{ "07930061010":{ "phone_number": "+917930061010", } } }
Scenario #3
If all ExoPhones connectivity is affected (CRITICAL):
{ "timestamp": "2018-08-22T15:19:23Z", "status_type":"CRITICAL", "incoming_affected":[ "07930061010", "08030752522" ], "outgoing_affected":[ "07930061010" ], "data":{ "07930061010":{ "phone_number": "+917930061010", }, "08030752522":{ "phone_number": "+918030752522", } } }
The HTTP Response for acknowledging the heartbeat webhook request should be 200 OK. All other non-2XX HTTP codes or if your server is unable to respond timely will indicate that you have not received the heartbeat and we will retry. In such retry cases, your server should be able to handle subsequent requests of the same heartbeat and the timestamp field in the heartbeat payload can be used to uniquely identify the most recent heartbeat.
Default Timeout = 15 seconds (Your servers should ideally consume heartbeat within milliseconds, but Exotel will wait maximum of 15 seconds for your endpoint to consume heartbeat and return 2XX HTTP code)
Retries = 2 (Exotel will retry twice in case of timeout or non-2XX HTTP code)
If your server needs to perform any complex logic, or make internal network calls, it is possible that the heartbeat webhook request might time out. For that reason, you might want to have your webhook endpoint immediately acknowledge receipt by returning a 2XX HTTP status code, and then perform the rest of its operations.
You should consume Heartbeat Webhook to continuously be aware of your ExoPhones health status and take necessary actions. In case any of your ExoPhone faces an issue as reported by webhook, you can query the GET ExoPhone Details for fetching further details. The GET endpoint can also be used to pull status per ExoPhone in case the webhook is not consumed by your servers (Exotel not being able to send or because your server is unable to process). As a best practice, polling the GET endpoint is not recommended. Exotel will throttle requests to GET ExoPhone Details endpoint with HTTP Code 429.
To get the details of a specific ExoPhone in your account including connectivity information, make an HTTP GET request to:
https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>
<your_api_key>
and <your_api_token>
with the API key and token created by you.<your_sid>
with your “Account sid”<subdomain>
with the region of your account
<your_api_key>
, <your_api_token>
and <your_sid>
are available in the API settings page of your Exotel Dashboard
This API only supports a JSON reponse.
curl -X GET https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>
var request = require('request'); var options = { url: 'https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>' }; function callback(error, response, body) { if (!error && response.statusCode == 200) { console.log(body); } } request(options, callback);
<?php include('vendor/rmccue/requests/library/Requests.php'); Requests::register_autoloader(); $headers = array(); $response = Requests::get('https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>', $headers);
import requests requests.get('https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>')
require 'net/http' require 'uri' uri = URI.parse("https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/incoming-phone-numbers/<exophone_sid>") response = Net::HTTP.get_response(uri) # response.code # response.body
HTTP Response:
{ "request_id": "0f403dff8d854ca08c570a94717aa7d9", "method": "GET", "http_code": 200, "metadata": { "page_size": 1, "page": 0 }, "response": [ { "code": 200, "error_data": null, "status": "success", "data": { "sid": "01139585476", "date_created": "2018-08-22T12:22:49Z", "date_updated": "2018-08-24T11:25:49Z", "friendly_name": "01139585476", "account_sid": "Exotel", "phone_number": "+911139585476", "capabilities": { "voice": true }, "country": "IN", "region": "DL", "one_time_price": "0.000000", "rental_price": "499.000000", "incoming_rate": "0.000000", "incoming_pulse": "60", "currency": "INR", "number_type": "Landline", "vanity_number": false, "voice_url": "https://my.exotel.com/Exotel/exoml/start_voice/XXX", "sms_url": "https://my.exotel.com/Exotel/exoml/start_sms/XXX", "uri": "/v2/accounts/Exotel/incoming-phone-numbers/01139585476", "connectivity": { "incoming_call": { "status": "active", "last_check_time": "2018-08-24T11:25:49Z", "alternate_exophone": null }, "outgoing_call": { "status": "active", "last_check_time": "2018-08-24T11:25:49Z", "alternate_exophone": null } } } } ] }
Description of Parameters:
Parameter Name |
Description |
request_id |
Random string to uniquely identify the request |
method |
HTTP request method (GET, POST, PUT, DELETE) |
http_code |
HTTP response code for your request like 200, 404, 429, 500 etc. |
metadata |
To provide metadata about the response. In case of GET for pagination (bulk), it'll contain:
|
response |
JSON array representing the response and contains below parameters:
"error_data": { "code": 1000, "description": "Not Found", "message": "Not Found" } In case of no errors, it’ll be null.
|
sid |
String; An alpha-numeric unique identifier of the ExoPhone. This can be different than the ExoPhone itself. |
date_created |
Time in format: RFC 3339; Date and time at which the ExoPhone was added to the account |
date_updated |
Time in format: RFC 3339; Date and time at which the details of the ExoPhone was last updated |
account_sid |
Exotel account SID |
phone_number |
The phone number value of the ExoPhone in E.164 format like +911139585476 |
friendly_name |
A freindly name that can be used to identify the ExoPhone |
capabilities |
These are the capabilities that are supported on this ExoPhone:
|
country |
ISO Country Code to which this ExoPhone belongs to |
region |
The telecom circle this ExoPhone belongs to. Refer here for list of possible telecom circles. |
one_time_price |
One time cost incurred while adding this ExoPhone to your account |
rental_price |
Double; Recurring monthly rental associated with this ExoPhone |
incoming_rate |
Double; The per pulse cost for incoming calls |
incoming_pulse |
Double; The duration of one pulse in seconds |
currency |
Double; The currency in which this ExoPhone is billed |
number_type |
Double; The type of the ExoPhone |
vanity_number |
Boolean; Indicates if this ExoPhone is a vanity number |
voice_url |
string; The Url to the flow to which incoming calls are connected to |
sms_url |
string; The Url to the flow to which incoming SMS are connected to |
uri |
string; The Url to the flow to which incoming calls are connected to |
connectivity |
JSON block representing connectivity information about the ExoPhone. It contains incoming_call, outgoing_call blocks which represent connectivity information for incoming call and outgoing call respectively. |
Description of 'connectivity' parameters:
Parameter Name |
Description |
status |
It represents the connectivity status for that functionality (incoming call or outgoing call). Possible values are
|
last_check_time |
Format: RFC 3339; timestamp representing when this number was checked last for connectivity |
alternate_exophone |
If available, this will provide alternate ExoPhones in JSON array format which can be used if the given ExoPhone is down. If there are no alternate ExoPhones available it will be populated as null |