This API will connect two phone numbers. This API would also mark the user as busy to prevent them to make/receive any other call and incoming calls would be routed to other users, if available. It does not require a user to be added mandatorily on the Exotel dashboard, to be able to mark them as busy. It will connect the number provided in the From field first and once the person picks up the call, it will connect the number provided in the To field. The From field should always contain your user/agent contact number or the SIP id (for VOIP calling).
To make a call connecting a user to a customer, you will need to make a HTTP POST request to
https://<your_api_key>:<your_api_token>@<subdomain>/v3/accounts/<your_sid>/calls
Example (For Singapore Stamp)-
https://<your_api_key>:<your_api_token>@ccm-api.exotel.com/v3/accounts/<your_sid>/calls
Example (For Mumbai Stamp)
https://<your_api_key>:<your_api_token>@ccm-api.in.exotel.com/v3/accounts/<your_sid>/calls
<your_api_key>
and <your_api_token>
with the API key and token created by you OR use Basic Authentication.<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
The following are the POST parameters supported with Content-Type: application/json
set in the header
Parameter |
Mandatory/ Optional |
Value/Description |
from |
Mandatory |
JSON block indicating the number to be dialed first (leg1). This should be your user/agent number. Currently it has two attributes:
If the contact_uri is already added to the Exotel dashboard as a user number, state_management will be ‘true’ by default. Example- { "from": { "contact_uri": "+9199XXXXXXX", "state_management": "true" } } If not set in E.164 format, our system will try to match it with a country and make a call. If landline number, prefix it with STD code; Ex: 080XXXX2400 |
to |
Mandatory |
JSON block containing the phone number of the customer (leg2) to be connected after the ‘from’ number is connected.
Example - { "to": { "contact_uri": "+9199XXXXXXX" } } |
virtual_number |
Mandatory |
ExoPhone (Virtual Number) present in your account in E.164 format or local format for Indian virtual numbers. This will be the number that will be used to make the call to both ‘from’ and ‘to’ numbers. |
recording |
Optional |
JSON block containing the recording related attributes. Currently these are record, channels and the ormat.
Please reach out to hello@exotel.com to get it enabled for your account before using this option. Example-
{ "recording": { "record": "true", "channels": "single", "format": "mp3-hq" } }
|
wait_audio_url |
Optional |
String; Play this audio to the caller. When the first leg (from) has to wait for the other leg (to) to pick up the call, the audio file specified in this parameter will be played. Please refer to this article to understand the format specifications of the audio file to be played (wav is only supported). Guidelines on usage:
Example: "http://{your_hosted_endpoint}/{audio file name}.wav" |
max_time_limit |
Optional |
Integer; The time limit (in seconds) that you want this call to last. The call will be cut after this time Default: 4 hours |
attempt_time_out |
Optional |
Integer; The time (in seconds) to ring the called parties (both first and second call leg) Default: 30 seconds. |
custom_field |
Optional |
String; Any application specific value like order id that will be passed back as a parameter in status_callback |
status_callback |
Optional |
Note - StatusCallBack delivery may be delayed or have failures due to multiple reasons like - network connectivity, customer web hook uptime, server failures etc. Customers are advised to implement fallback to call details API for fetching the call status.
method: Default: POST Allowed: GET and POST content_type: The HTTP header ‘Content-Type’ using which the status_callback webhook will be triggered to your URL. Can be:
Example:
{ "status_callback": [ { "event": "answered", "url": "", "method": "POST", "content_type": "application/json" }, { "event": "terminal", "url": "", "method": "GET", "content_type": "application/json" } ] }
|
playback |
Optional |
Array: Contains the playback related attributes. Currently, the supported attributes are:
Example:
{ "playback": [ { "event": "start", "to": "both", "value": "" } }
|
streaming |
Optional |
JSON block containing the streaming related attributes. Currently, these are:
Example:
{ "streaming": { "url": "", "begin": "from_leg_connect" } }
|
{ "from": { "contact_uri": "8516043026", "state_management": true }, "to": { "contact_uri": "7987616844" }, "recording": { "record": true, "channels": "single" }, "virtual_number": "+912241499102", "max_time_limit": 4000, "attempt_time_out": 45, "custom_field": "bilbo_test_call", "status_callback": [ { "event": "terminal", "url": "https://webhook.site/aecd85dc-f959-48b5-abaf-d45189037e09" } ] }
Parameter Name |
Type & Value |
request_id |
This indicates the unique id of the request. Useful for debugging and tracing purposes. |
method |
This indicates the HTTP method for the request such as GET/POST/PUT etc. |
http_code |
This indicates the HTTP code for the request such as 200, 400, 500 etc. |
response |
Response block contains the user device record matching the request URI. The block contains
|
Parameter |
Value/Description |
sid |
string; an alpha-numeric unique identifier of the call |
direction |
|
virtual_number |
This is your ExoPhone/Exotel Virtual Number |
state |
|
status |
Overall call status, could be one of:
|
legs |
This URL can be used as a GET API to fetch the legs information of a given call_sid |
created_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) at which the user initiated the API |
updated_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) at which the status of the call was last updated in our system |
start_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) when the call request was initiated to the operator |
end_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) when the call was completed |
total_duration |
Total call duration in seconds (From start_time to end_time) |
total_talk _time |
Total time a customer was on call. If there were more than one conversation, it would be the sum of all conversations. Eg- User 1 spoke to Customer for 5 minutes and transferred to User 2 and spoke to customer for 10 minutes, total_talk_time for the call would be 15 minutes |
custom_field |
The value that was passed in the custom_field parameter of the API (if set during the request) will be populated here. |
app_id |
Flow ID which was used at the start of the call. Null if flow was not used. |
app_name |
Flow Name which was used at the start of the call. Null if flow was not used |
digits |
DTMF digits pressed during the call separated by “-” for different applets. Similar to how it is represented in Call Reports |
recordings |
Array; It will contain all recordings associated with the call. Each array will contain
|
*Some of the above parameters can be null for POST response as they'll be not set immediately after call creation
{ "request_id": "1e2acb77c0f84db4821e765510fdecff", "method": "POST", "http_code": 200, "metadata": null, "response": { "code": 200, "error_data": null, "status": "success", "call_details": { "sid": "3f3fedf8f0928550a60bfa6302dc16b2", "direction": "outbound", "virtual_number": "02241499102", "state": "active", "status": null, "legs": "/v3/accounts/Exotel/calls/3f3fedf8f0928550a60bfa6302dc16b2/legs", "created_time": "2022-11-02 23:49:51+05:30", "updated_time": "2022-11-02 23:49:52+05:30", "start_time": "2022-11-02 23:49:52+05:30", "end_time": null, "total_duration": null, "total_talk_time": null, "custom_field": "bilbo_test_call", "app_id": null, "app_name": null, "digits": null, "recordings": null } } }
Exotel will perform an asynchronous HTTP request to the status_callback URL you have specified in your request (if any) based on the status_callback event type and the request method opted for. List of parameters which will be sent as part of status_callback.
Parameter |
Value/Description |
event_details |
JSON block containing the status callback event related attributes. Currently, these are:
|
call_details |
This block will contain the information corresponding to the response array element and will contain the fields for a user record as explained under the 'call_details' block. |
{ "event_details": { "event_type": "terminal" }, "call_details": { "sid": "0ed3bd4755078e1f9f64d2de75ce16b3", "direction": "outbound", "virtual_number": "+912241499102", "state": "terminal", "status": "completed", "legs": "/v3/accounts/Exotel/calls/0ed3bd4755078e1f9f64d2de75ce16b3/legs", "created_time": "2022-11-03 00:18:32+05:30", "updated_time": "2022-11-03 00:19:02+05:30", "start_time": "2022-11-03 00:18:38+05:30", "end_time": "2022-11-03 00:19:02+05:30", "total_duration": null, "total_talk_time": 11, "custom_field": "bilbo_test_call", "app_id": null, "app_name": null, "digits": null, "recordings": [ { "url": "https://s3-ap-south-1.amazonaws.com/exotel-mum1-recordings/Exotel/0ed3bd4755078e1f9f64d2de75ce16b3.mp3" } ] } }
HttpCode | Code | Description |
401 | 1010 |
Authentication failed
|
404 | 10731 |
User not found
|
409 | 1012 |
User device is unavailable
|
409 | 10705 |
User device is unverified
|
409 | 10706 |
User device is currently busy
|
404 | 10806 |
No device found for user
|
404 | 1017 |
AccountSid not found
|
404 | 10702 |
User Device not found
|
409 | 10705 |
User device is unverified
|
404 | 1021 |
Call not found / unsupported in this API
|
404 | 1022 |
Call not found / unsupported in this API
|
400 | 1001 |
account_sid is mandatory
|
400 | 1002 |
Valid values for RecordingChannels are single, dual
|
500 | 1100 |
Internal Server Error
|
500 | 1101 |
Internal Server Error
|
500 | 1200 |
Internal Server Error
|
404 | 10703 |
Device is currently unavailable (turned off)
|
500 | 1203 |
Internal Server Error
|
500 | 1300 |
Internal Server Error
|
405 | 10712 |
VOIP calls are not allowed
|
500 | 1500 |
Internal Server Error
|
500 | 1600 |
Internal Server Error
|
500 | 1601 |
Internal Server Error
|
500 | 1800 |
Internal Server Error
|
500 | 3040 |
Internal Server Error
|
500 | 3042 |
Internal Server Error
|
404 | 3043 |
Call not found / unsupported in this API
|
404 | 3044 |
Call not found / unsupported in this API
|
404 | 3045 |
Call not found / unsupported in this API
|
500 | 3046 |
Internal Server Error
|
500 | 3075 |
Internal Server Error
|
500 | 3080 |
Internal Server Error
|
500 | 4060 |
Internal Server Error
|
404 | 10716 |
Given virtual_number not found
|
404 | 10706 |
User device is currently busy
|
For handling incoming calls, you can build call flows on Exotel using various applets. The CCM programmable version of the Connect applet enables the call flow to be configured for connecting the caller to a user along with additional parameters returned from your URL which can be configured dynamically per call. These include configurations such as number state management, recording of the call, maximum conversation time, etc. For detailed documentation of the same, refer here.
The dynamic URL should return a user's phone number or the SIP Id.
NOTE: This feature is currently in private beta and can be enabled on request via hello@exotel.com
To get the details of a call, you will need to make an HTTP GET request to
https://<your_api_key>:<your_api_token><subdomain>/v3/accounts/<your_sid>/calls/<call_sid>
Example (For Singapore Stamp)-
https://<your_api_key>:<your_api_token>@ccm-api.exotel.com/v3/accounts/<your_sid>/calls/<call_sid>
Example (For Mumbai Stamp)
https://<your_api_key>:<your_api_token>@ccm-api.in.exotel.com/v3/accounts/<your_sid>/calls/<call_sid>
<your_api_key>
and <your_api_token>
with the API key and token created by you OR use Basic Authentication.<your_sid>
with your “Account sid”<subdomain>
with the region of your account<call_sid>
with the Call Sid provided during Click to Call API request.<your_api_key>
, <your_api_token>
and <your_sid>
are available in the API settings page of your Exotel Dashboard
curl -X GET https://:/v3/accounts//calls/ -H 'content-type: application/json'
var request = require("request"); var options = { method: 'GET', url: 'https://:/v3/accounts//calls/', headers: { 'content-type': 'application/json' } }; request(options, function (error, response, body) { if (error) throw new Error(error); console.log(body); });
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
‘content-type’ => ‘application/json’,
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
import requests url = "https://:/v3/accounts//calls/" headers = { 'content-type': "application/json" } response = requests.request("GET", url, headers=headers) print(response.text)
package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://:/v3/accounts//calls/" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("content-type", "application/json") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) }
Parameter Name |
Type & Value |
request_id |
This indicates the unique id of the request. Useful for debugging and tracing purposes. |
method |
This indicates the HTTP method for the request such as GET/POST/PUT etc. |
http_code |
This indicates the HTTP code for the request such as 200, 400, 500 etc. |
response |
Response block contains the user device record matching the request URI. The block contains
|
Parameter |
Value/Description |
sid |
string; an alpha-numeric unique identifier of the call |
direction |
|
virtual_number |
This is your ExoPhone/Exotel Virtual Number |
state |
|
status |
Overall call status, could be one of:
|
legs |
This URL can be used as a GET API to fetch the legs information of a given call_sid |
created_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) at which the user initiated the API |
updated_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) at which the status of the call was last updated in our system |
start_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) when the call request was initiated to the operator |
end_time |
Time in format YYYY-MM-DD HH:mm:ss+|–hh:mm; Date and time (along with the offset) when the call was completed |
total_duration |
Total call duration in seconds (From start_time to end_time) |
total_talk _time |
Total time a customer was on call. If there were more than one conversation, it would be the sum of all conversations.
Eg- User 1 spoke to Customer for 5 minutes and transferred to User 2 and spoke to customer for 10 minutes, total_talk_time for the call would be 15 minutes |
custom_field |
The value that was passed in the custom_field parameter of the API (if set during the request) will be populated here. |
app_id |
Flow ID which was used at the start of the call. Null if flow was not used. |
app_name |
Flow Name which was used at the start of the call. Null if flow was not used |
digits |
DTMF digits pressed during the call separated by “-” for different applets. Similar to how it is represented in Call Reports |
recordings |
Array; It will contain all recordings associated with the call. Each array will contain
|
{ "request_id": "62bd4015e8c04ecea3a5fbd7272f95ae", "method": "GET", "http_code": 200, "metadata": null, "response": { "code": 200, "error_data": null, "status": "success", "call_details": { "sid": "cabfb1dfa8c5e1c7f2c458423b7716b3", "direction": "outbound", "virtual_number": "+911414941199", "state": "active", "status": null, "legs": "/v3/accounts/Exotel/calls/cabfb1dfa8c5e1c7f2c458423b7716b3/legs", "created_time": "2022-11-03 22:54:40+05:30", "updated_time": "2022-11-03 22:54:58+05:30", "start_time": "2022-11-03 22:54:57+05:30", "end_time": "1970-01-01 05:30:00+05:30", "total_duration": null, "total_talk_time": null, "custom_field": null, "app_id": null, "app_name": null, "digits": null, "recordings": null } } }
{ "request_id": "9107ba6bdfc5493e806b7ea82706f2e0", "method": "GET", "http_code": 200, "metadata": null, "response": { "code": 200, "error_data": null, "status": "success", "call_details": { "sid": "cabfb1dfa8c5e1c7f2c458423b7716b3", "direction": "outbound", "virtual_number": "+911414941199", "state": "terminal", "status": "completed", "legs": "/v3/accounts/Exotel/calls/cabfb1dfa8c5e1c7f2c458423b7716b3/legs", "created_time": "2022-11-03 22:54:40+05:30", "updated_time": "2022-11-03 22:56:05+05:30", "start_time": "2022-11-03 22:54:57+05:30", "end_time": "2022-11-03 22:56:04+05:30", "total_duration": null, "total_talk_time": 59, "custom_field": null, "app_id": null, "app_name": null, "digits": null, "recordings": [ { "url": "https://s3-ap-south-1.amazonaws.com/exotel-mum1-recordings/Exotel/cabfb1dfa8c5e1c7f2c458423b7716b3.mp3" } ] } } }
NOTE:- To enable this API in your account, please reach out to hello@exotel.com
To get the different call legs associated with a call, you need to make an HTTP GET request to
https://<your_api_key>:<your_api_token><subdomain>/v3/accounts/<your_sid>/calls/<call_sid>/legs
Example (For Singapore Stamp)-
https://<your_api_key<your_api_token>@ccm-api.exotel.com/v3/accounts/<your_sid>/calls/<call_sid>/legs
Example (For Mumbai Stamp)
https://<your_api_key<your_api_token>@ccm-api.in.exotel.com/v3/accounts/<your_sid>/calls/<call_sid>/legs
<your_api_key>
and <your_api_token>
with the API key and token created by you OR use Basic Authentication.<your_sid>
with your “Account sid”<subdomain>
with the region of your account<call_sid>
with the Call Sid provided during Click to Call API request.<your_api_key>
, <your_api_token>
and <your_sid>
are available in the API settings page of your Exotel Dashboard
curl -X GET https://<your_api_key@ccm-api.exotel.com/v3/accounts//calls//legs -H 'content-type: application/json'
Parameter Name |
Type & Value |
request_id |
This indicates the unique id of the request. Useful for debugging and tracing purposes. |
method |
This indicates the HTTP method for the request such as GET/POST/PUT etc. |
http_code |
This indicates the HTTP code for the request such as 200, 400, 500 etc. |
response |
Response block contains the leg details for call sid passed in the path parameter. The block contains
|
Parameter Name |
Description |
---|---|
sid |
string; an alpha-numeric unique identifier of the call |
from |
Array of JSON blocks containing information about the 'from' leg. For outgoing calls, this array will contain all the user call leg (s) information. For incoming calls, this array will contain the customer call leg information. The JSON block contains:
|
to |
Array of JSON blocks containing information about the 'to' leg. For outgoing calls, this array will contain the customer call leg information. For incoming calls, this array will contain all the user call leg (s) information. The JSON block contains:
|
{ "request_id": "faf6d9fd87eb4dd6aef3967c40e369ed", "method": "GET", "http_code": 200, "metadata": null, "response": { "code": 200, "error_data": null, "status": "success", "leg_details": { "call_sid": "f1ca1057692d586b23b4e7ffcc3216mk", "account_sid": "exotel", "from": [ { "sid": "213f2560d153d744cd61eb81a98616ak", "name": "Aditya Sharma", "contact_uri": "0987xxxxxxx", "date_created": "2020-09-15 11:01:20+05:30", "date_updated": "2020-09-15 11:02:20+05:30", "status": "completed" }, { "sid": "813f2660d153d744cd61eb81a98616ak", "name": null, "contact_uri": "09976xxxxxx", "date_created": "2020-09-15 11:03:20+05:30", "date_updated": "2020-09-15 11:04:20+05:30", "status": "completed" } ], "to": [ { "sid": "922g2560d153d744cd61eb81a92616am", "name": "Vikas Sharma", "contact_uri": "sip:vikassffbbfc17", "date_created": "2020-09-15 11:01:20+05:30", "date_updated": "2020-09-15 11:02:20+05:30", "status": "no-answer", "group_id": 123456, "group_name": "test_group" }, { "sid": "544r1560d153d754cd61tb83a77616ak", "name": "Sanjay Mishra", "contact_uri": "08887xxxxxx", "date_created": "2020-09-15 11:03:20+05:30", "date_updated": "2020-09-15 11:04:20+05:30", "status": "completed", "group_id": null, "group_name": null } ] } } }
Http Code |
Error Code |
Description |
---|---|---|
500 |
- |
Internal Server Error |
500 |
10743 |
Legs not found |
500 |
10715 |
Error retrieving leg details |
429 |
10724 |
Too many requests (from Mavrix) |
404 |
10744 |
Call not found |
404 |
1017 |
Tenant not found |
401 |
1010 |
Authentication failed |