https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns
This API supports JSON response only.
<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
The following are the POST parameters:
Parameter Name | Mandatory/Optional | Value |
from | Mandatory | Comma separated list of phone numbers that will be called. Preferably in E.164 format. If not set, our system will try to match it with a country and make a call. If landline number, prefix it with STD code; Ex: 0XXXXXX2400. Default is 1 and Max is 5000 |
lists | Optional |
Array of listSid. Up to 5 listSid can be part of one single campaign if optional parameter campaign type is selected as "static". If optional parameter campaign type is selected as "dynamic" then only one listSid is allowed. If no campaign type parameter is selected then the campaign by default runs as a "static" campaign. Either 'from' parameter or 'lists' parameter should be present in the API request |
caller_id | Mandatory | This is your ExoPhone (pick one from here) |
campaign_type | Optional |
This will be "static" by default. In case, a Dynamic Campaign has to be scheduled then this value will be "dynamic" |
flow_type | Optional |
In case of Creating an IVR through the campaign module, defining "ivr" is mandatory. The parameter name is "ivr". If read_via_text is opted then this value will be "greeting". This is not applicable if you are selecting a flow. |
repeat_menu_attempts | Optional |
If the flow_type is selected as "ivr" then this value can be specified to repeat the IVR menu. The default value will be 0 if the flow_type is set as "ivr". This field is not applicable if flow_type is "greeting" |
url | Optional |
Only applicable if you are selecting a call flow. http://my.exotel.com/{your_sid}/exoml/start_voice/{app_id} where app_id is the identifier of the flow (or applet) that you want to connect to once the from number picks up the call. You can get the app_id from your Exotel Dashboard |
read_via_text | Optional |
If the flow_type is opted for "ivr" or "greeting", then this field has to be entered with the content that has to be played out to the caller. You can enter a static content(no variables) or Dynamic content. In case, dynamic content is entered then "@@" has to be entered with the header value. Ensure that the header is the exact match from the list uploaded. For ex: If the header name in the file is FirstName then in the content entered here the dynamic variable has to be "@@FirstName" If flow/url is opted then this field would not be required.
|
name | Optional |
It's an optional parameter in the request but mandatory in the response. It is used to define the name of the campaign. It should be greater than 3 characters and if not passed, its default value will be created using the 'AccountSID CurrentDate CurrentTime' and passed in the response. Example: exotel 2021-06-04 11:11:10 |
type | Optional |
It's an optional parameter in the request but mandatory in the response. It's allowed (and default) value is 'trans'. If not passed in the request, we will create campaign as type 'trans' and pass this parameter in the API response. As per regulations, we support only transactional type of campaigns. |
call_duplicate_numbers |
Optional |
Type: boolean Allowed Values: 'true' & 'false' Default Value: 'false' If 'true', Campaign will try calling the duplicate numbers present in the list(s). If 'false', Campaign will call any number in the list(s) only once. It is independent of the 'retry' functionality. |
retries | Optional |
Object;Retry logic in case the calls are not successful.
|
schedule | Optional |
Array;Determines when to start and end a campaign in RFC 3339 date-time
|
call_status_callback | Optional |
When the call completes, an HTTP POST will be made to the provided URL with the following four parameters:
|
call_schedule_callback | Optional |
When all calls to a number were completed including retries, an HTTP POST will be made to the provided URL with the following four parameters:
|
status_callback | Optional |
When the call campaign starts or ends, an HTTP POST will be made to the provided URL with the following four parameters:
|
mode | Optional |
This can be "auto" or "custom". Auto- This will be a default in which the campaign service will distribute the throttle of the campaign automatically Custom- The throttle value can be set based on the desired campaign priority. |
throttle | Optional |
Only if Mode is selected as "Custom" this parameter will be applicable. The allowed value will be between 1 to (Campaign account throttle minus 1). To know your Campaign Account throttle you can visit the Campaign settings page of your Exotel Account. |
custom_field | Optional | Any application-specific value that will be passed back as a parameter while doing a GET request to the URL mentioned in your Passthru Applet or Greetings Applet.It is also provided as part of the campaigns report |
curl --location --request POST 'https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns' --header 'Content-Type: application/json' --data-raw '{ "campaigns": [ { "name": "Exotel_2022-08-08 16:33:22", "caller_id":"0xxxx83280", "lists":["b7799a24becf436da672163858e8165d"], "campaign_type":"dynamic", "flow_type":"ivr", "read_via_text":"Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}" } ] }'
var request = require('request'); var options = { 'method': 'POST', 'url': 'https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns', 'headers': { 'Content-Type': 'application/json' }, body: JSON.stringify({ "campaigns": [ { "caller_id": "0XXXX83280", "lists": [ "b7799a24becf436da672163858e8165d" ], "campaign_type": "dynamic", "flow_type": "ivr", "read_via_text": "Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}" } ] }) }; request(options, function (error, response) { if (error) thrownewError(error); console.log(response.body); });
<?php $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS =>'{ "campaigns": [ { "caller_id":"0XXXX83280", "lists":["b7799a24becf436da672163858e8165d"], "campaign_type":"dynamic", "flow_type":"ivr", "read_via_text":"Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}" } ] }', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json' ), )); $response = curl_exec($curl); curl_close($curl); echo $response;
import requests import json url = "https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns" payload = json.dumps({ "campaigns": [ { "caller_id": "0XXXX83280", "lists": [ "b7799a24becf436da672163858e8165d" ], "campaign_type": "dynamic", "flow_type": "ivr", "read_via_text": "Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}" } ] }) headers = { 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text)
package main import ( "fmt" "strings" "net/http" "io/ioutil" ) func main() { url := "https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/campaigns" method := "POST" payload := strings.NewReader(`{ "campaigns": [ { "caller_id":"0XXXX683280", "lists":["b7799a24becf436da672163858e8165d"], "campaign_type":"dynamic", "flow_type":"ivr", "read_via_text":"Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}" } ] }`) client := &http.Client { } req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) return } req.Header.Add("Content-Type", "application/json") res, err := client.Do(req) if err != nil { fmt.Println(err) return } defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println(err) return } fmt.Println(string(body)) }
HTTP Response:
{ "request_id": "0a6d6fccb66e48699b77058554b507e9", "method": "POST", "http_code": 200, "response": [ { "code": 200, "error_data": null, "status": "success", "data": { "id": "59beaff7d1c887e877a3b5942bc389fd1688", "account_sid": "Exotel", "name": "Exotel_2022-08-08 16:33:22", "type": "trans", "caller_id": "0XXXX83280", "campaign_type": "dynamic", "read_via_text": "Hi @@Name @@Last name , your order ID is @@Order ID . Press 1 to proceed, press 2 to abort", "repeat_menu_attempts": 0, "flow_type": "ivr", "lists": [ "b7799a24becf436da672163858e8165d" ], "url": "http://my.exotel.com/Exotel/exoml/start_voice/528696", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "schedule": { "send_at": "2022-08-08T16:34:22+05:30", "end_at": "2022-09-07T16:34:22+05:30" }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "custom_field": "{"name": "yo"}", "date_created": "2022-08-08T16:33:22+05:30", "date_updated": "2022-08-08T16:33:22+05:30", "status": "Created", "call_status_callback_params": null, "call_duplicate_numbers": false, "stats": { "created": 0, "in-progress": 0, "retry": 0, "retrying": 0, "failed": 0, "failed-dnd": 0, "invalid": 0, "paused": 0, "failed-no-attempt": 0, "completed": 0, "pending": 0 }, "mode": "auto" }, "summary": { "campaign_sid": "59beaff7d1c887e877a3b5942bc389fd1688", "call_scheduled": 0, "call_initialized": 0, "call_completed": 0, "call_failed": 0, "call_inprogress": 0, "DateCreated": "2022-08-08T16:33:22.749572683+05:30" } } ] }
Description of parameters mentioned in the above response:
Parameter Name | Type & Value |
request_id | string; Random string to uniquely identify the request |
method | string; HTTP request method (GET, POST, PUT, DELETE) |
http_code | string; HTTP response code for your request |
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.
|
id | Campaigns identifier |
account_sid | Exotel account SID |
from | Array; phone numbers that we will be attempted as part of this campaign |
caller_id | The Exophone that is used to initiate calls for this campaign |
url | Identifier of the flow (or applet) that you want to connect to once the from number picks up the call |
retries |
JSON; The retries that were configured as part of this campaign:
|
schedule |
JSON; The start and end time that were configured for this campaign:
|
status_callback | URL to which an HTTP POST will be made upon completion of the campaign |
call_status_callback | URL to which an HTTP POST will be made upon completion of a call in the campaign |
call_schedule_callback | URL to which an HTTP POST will be made upon completion of one call schedule which includes retries |
custom_field | Application specific value that was be passed back as a parameter to the campaign creation |
date_created | Time in format: RFC 3339; Date and time at which the resource was created in the system |
date_updated | Time in format: RFC 3339; Date and time at which the resource was updated in the system |
status |
The current status of the campaign. Campaings have both intermediate and final status:
|
Some of the parameters of a campaign are updated asynchronously after the call(s) ends. So it might take some time after the call ends (~ 2 mins on an average) for these parameters to be populated correctly.
There are multiple status callbacks that Campaign API serves when specified as part of POST request. Sample responses of each of them are given below
{ "request_id": "745d624f47004b71bf72e6cb7d58a25b", "method": "POST", "http_code": 200, "response": [ { "code": 200, "error_data": null, "status": "success", "data": { "name": "diwali_campaign", "type": "trans", "id": "909d2a2ba53ce07f3784668b938eb44914bo", "account_sid": "exotel8u3", "caller_id": "0XXXX720616", "lists": [ "68f443cd3e764ad1ae7d82ad27f0af72" ], "url": "http://my.exotel.com/<your_sid>/exoml/start_voice/<app_id>", "retries": { "number_of_retries": 1, "interval_mins": 1, "mechanism": "Exponential", "on_status": [ "failed", "busy" ] }, "schedule": { "send_at": "2019-01-20T21:15:00+05:30", "end_at": "2019-01-20T21:16:00+05:30" }, "status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_status_callback": "https://mycallback.sampledomain.in/1gvta9f1", "call_schedule_callback": "https://mycallback.sampledomain.in/1gvta9f1", "date_created": "2019-01-20T21:10:00+05:30", "date_updated": "2019-01-20T21:10:00+05:30", "status": "Created", "call_status_callback_params": null, "call_duplicate_numbers": true, "stats": { "created": 0, "in-progress": 0, "retry": 0, "retrying": 0, "failed": 0, "failed-dnd": 0, "invalid": 0, "paused": 0, "failed-no-attempt": 0, "completed": 0 } }, "summary": { "campaign_sid": "75ccf890dd85a87c138396b8abfec9251579", "call_scheduled": 0, "call_initialized": 0, "call_completed": 0, "call_failed": 0, "call_inprogress": 0, "DateCreated": "2019-01-20T21:10:00+05:30" } } ] }
Call Schedule Status Callback:
{ "campaign_sid":"44a89f18b291441786f6be2dacee0366", "to": "+91XXXX161323", "from": "XXXXXX74100", "date_created": "2019-01-10T17:08:00+05:30", "date_updcated": "2019-01-10T17:08:00+05:30", "call_sids": [ { "call_sid": "73f57c6bccd64a29a0cb4806af05cdbe", "status": "completed" } ], "status": "completed" }
Campaigns Status Callback:
{ "campaign_sid": "44a89a18b291441786f6be2dfcee0366", "date_created": "2019-01-10T17:08:00+05:30", "date_updated": "2019-01-10T17:08:00+05:30", "date_started": "2019-01-10T17:08:00+05:30", "status": "completed", "reports": "https://campaigns-reports.s3.ap-southeast-1.amazonaws.com/000d3b00d7651e088e1b42be5d89xxx.csv" }
The default Call Capacity of a campaign is 60 calls per minute. If you want to increase the capacity (fast calling), you have to raise a request to the support team to increase it.