×

This API will send SMSes to different numbers with different message content for each number. To send SMS through our API, you will need to make a HTTP POST request to

POST

https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend

  • Replace <your_api_key> and <your_api_token> with the API key and token created by you.
  • Replace <your_sid> with your “Account sid”
  • Replace <subdomain> with the region of your account
    1. <subdomain> of Singapore cluster is @api.exotel.com
    2. <subdomain> of Mumbai cluster is @api.in.exotel.com

<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

Optional

  • Specify one of your ExoPhones
  • For transactional SMSes, the SenderID (When you buy an ExoPhone, you will be asked to enter a 6-letter sender ID from which your SMSes will be sent. For Eg: LM-EXOTEL or LM-WEBDEV etc.) will be the one that corresponds to the ExoPhone
  • For promotional SMSes, the SenderID will anyways be a generic numeric one (Ex: LM-123456)
  • Will be used in cases where From is missing in Messages object
  • If not set, default approved SENDER ID as per account will be used

Messages

Mandatory

Array of message objects, wherein each object contains parameters about individual SMS:

  • To (Mandatory): Mobile number to which SMS has to be sent. Preferably in E.164 format. If not set, our system will try to match it with a country and route the SMS
  • Body (Mandatory): Content of your SMS; Max Length of the body cannot exceed 2000 characters
  • From (Optional): ExoPhone or approved SENDER ID. If not provided, will use outer From
  • SmsType (Optional): Applicable only for SMS sent by Indian businesses to Indian destination numbers. For International entities, the step to add a Template on the Exotel dashboard is mandatory.

This optional parameter can be used to skip template addition on Exotel Dashboard and configure SMS type based on the template registered on DLT in India. 

Possible values-

  • transactional (OTP or Service Implicit content)
  • transactional_opt_in (Service Explicit content)
  • promotional (Promotional content with numeric header)

If not set or incorrectly passed, Exotel will look up if content matches Templates added on Exotel for fetching SMS Type and DLT details.

  • DltTemplateId (Optional): Applicable only for SMS sent by Indian businesses to Indian destination numbers.

    Content Template Id against the SMS body registered with DLT (Distributed Ledger Technology) portal of operators in India. (Learn More about DLT)

EncodingType

Optional

Message type of SMS; plain or unicode

ShortenUrl  Optional

Whether to shorten the URLs present in the SMS. Can be: "true" or "false".
Please note that it is a chargeable feature and you can refer to Support article to understand more and get it enabled for your account.

ShortenUrlParams

[Header]

Optional

Applicable only for SMS sent by Indian businesses to Indian destination numbers.

Header that is part of the whitelisted Shortened URL on the DLT(Distributed Ledger Technology) platform of your choice.  Please ensure that this is an exact match with the header that is part of the whitelisted URL to avoid message failure

ShortenUrlParams
[CustomDomain]
Optional

Whether you want the short URL to start with default domain- exo.tl or you want to provide a custom domain of your own choice.

      If custom domain is not present or empty, we will use the default domain(exo.tl)

      If custom domain is given in the request it will be used to form the short URL

Note : Clients will have to route the traffic on their custom domain to exo.tl domain, this is a change on your domain management system

ShortenUrlParams
[Tracking]

Optional 

Whether to track the URLs present in the SMS. Can be: "true" or "false". "ShortenUrl" needs to be "true" for Tracking to work.

This feature is currently available to select customers. For early access, please fill this form. 

ShortenUrlParams
[ClickTrackingCallbackUrl]
Optional 

Once someone clicks on the shortened URL,  Exotel will do a POST callback to your end point if the URL is set as a parameter in the API.  

Below are the parameters: 

sid - The Sid (unique id) of the shortened URL  

short_url - The complete shortened URL

short_code - Key of the shortened URL 

long_url - Original URL which is shortened

Tracking - Whether to track the URLs present in the SMS

custom_field - custom field passed in SMS API request String value

Expires_at -  Date Time in ISO format when link will expire

Created_time - Date Time in ISO format when URL is created

Last_viewed -  Date Time in ISO format when link was visited last

Total_clicks  - count of total views of short url

Account_sid -  Exotel’s unique Account SID

Country_code - Country code of the customer who received the SMS

Date_created - Date Time in ISO format when link was created 

Sms_sid - The Sid (unique id) of the SMS, this SID can be used to track the SMS

To -  Contact number of the customer who clicked on the URL

city - City where the shorten URL is clicked

Country - Country code where shorten URL is clicked

IP - IP address where shorten URL is clicked

Postal code - Postal code where shorten URL is clicked 

Region - Region where shorten URL is clicked

Accuracy radius - Aproximate accuracy radius where shorten URL is clicked 

OS_version - OS version of the customer who clicked the shorten URL 

OS_name - OS name of the customer who clicked the shorten URL 

Device_name - Device name of the customer who clicked the shorten URL 

Platform type - Platform where shorten URL is clicked 

StatusCallback

Optional

After every SMS reaches terminal state (sent/failed/failed-dnd), Exotel will do a POST callback to your end point if the URL is set as a parameter in the API. Content-type for the POST callback is application/x-www-form-urlencoded Below are the parameters:

  • SmsSid - The Sid (unique id) of the SMS that you got in response to your request
  • To - Mobile number to which SMS was sent
  • Status - one of: queued, sending, submitted, sent, failed-dnd, failed
  • DetailedStatus - Human readable word that explains what happened to the message 
  • DetailedStatusCode - Exotel’s Detailed Status code corresponding to the DetailedStatus 
  • DateSent - The date on which the message was sent
  •  SmsUnits - The number of  SMS units being sent
  • CustomField - The custom field that was set in the POST request. (Will be returned only if it was set)

This feature is currently available to select customers. For early access, please fill this form. 

DltEntityId

Optional

Applicable only for SMS sent by Indian businesses to Indian destination numbers.

Your Entity Id as registered on DLT (Distributed Ledger Technology) portal of operators in India. (Learn More about DLT)

CustomField

Optional

Set a Custom Field relevant to your use case while sending an SMS. E.g Order ID, Payment ID, Login Attempt etc

Priority

Optional

Priority of the SMS; normal or high. Priority=high parameter should only be used for OTP SMSes (Bank or Delivery). Using it for any other SMS may impact your delivery

curl -X POST https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend \
-d "From=0XXXXXX4890" \
-d "Messages[0][Body]=Hello World one" \
-d "Messages[0][To]=XXXXX30240" \
-d "Messages[1][Body]=Hello World two" \
-d "Messages[1][To]=XXXXX30241" \
            
var request = require('request');

var dataString = 'From=0XXXXXX4890&Messages[0][Body]=Hello World one&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241';

var options = {
    url: 'https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend',
    method: 'POST',
    body: dataString
};

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();
$data = array(
    'From' => '0XXXXXX4890',
    'Messages' => array(array('To' => 'XXXXX30240', 'Body' => 'Hello World one'), array('To' => 'XXXXX30241', 'Body' => 'Hello World two')),
);
$response = Requests::post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', $headers, $data);
            
import requests

data = {
  'From': '0XXXXXX4890',
  'Messages[0][Body]': 'Hello World one',
  'Messages[0][To]': 'XXXXX30240',
  'Messages[1][Body]': 'Hello World two',
  'Messages[1][To]': ' XXXXX30241'
}

requests.post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', data=data)
            
require 'net/http'
require 'uri'

uri = URI.parse("https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend")
request = Net::HTTP::Post.new(uri)
request.body = "From=0XXXXXX4890&Messages[0][Body]=Hello World one&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

# response.code
# response.body
            
curl -X POST https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend \
-d "From=0XXXXXX4890" \
-d "Messages[0][Body]=Hello World one" \
-d "Messages[0][To]=XXXXX30240" \
-d "Messages[1][Body]=Hello World two" \
-d "Messages[1][To]=XXXXX30241" \
-d "ShortenUrl=true" \ 
-d "ShortenUrlParams[Header]=EXOTEL"
-d "ShortenUrlParams[Tracking]=true"\ 
-d "ShortenUrlParams[ClickTrackingCallbackUrl]=https://www.google.co.in/"
            
var request = require('request');
var dataString = 'From=0XXXXXX4890&Messages[0][Body]=Hello World one&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241&ShortenUrl=true&ShortenUrlParams[Header]=EXOTEL&ShortenUrlParams[Tracking]=true&ShortenUrlParams[ClickTrackingCallbackUrl]=https://www.google.co.in/';
var options = {
    url: 'https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend',
    method: 'POST',
    body: dataString
};
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();
$data = array(
    'From' => '0XXXXXX4890',
    'Messages' => array(array('To' => 'XXXXX30240', 'Body' => 'Hello World one'), array('To' => 'XXXXX30241', 'Body' => 'Hello World two')),
    'ShortenUrl' => 'true', 
    'ShortenUrlParams[Header]' => 'EXOTEL',
    'ShortenUrlParams[Tracking]' => 'true',
    'ShortenUrlParams[ClickTrackingCallbackUrl]' => 'https://www.google.co.in/
);
$response = Requests::post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', $headers, $data);
            
import requests

data = {
  'From': '0XXXXXX4890',
  'Messages[0][Body]': 'Hello World one',
  'Messages[0][To]': 'XXXXX30240',
  'Messages[1][Body]': 'Hello World two',
  'Messages[1][To]': ' XXXXX30241', 
  'ShortenUrl' : 'true',
  'ShortenUrlParams[Header]' : 'EXOTEL',
  'ShortenUrlParams[Tracking]' : 'true', 
  'ShortenUrlParams[ClickTrackingCallbackUrl]' : 'https://www.google.co.in
}

requests.post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', data=data)
            
require 'net/http'
require 'uri'

uri = URI.parse("https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend")
request = Net::HTTP::Post.new(uri)
request.body = "From=0XXXXXX4890&Messages[0][Body]=Hello World one&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241&ShortenUrl=true&ShortenUrlParams[Header]=EXOTEL&ShortenUrlParams[Tracking]=true&ShortenUrlParams[ClickTrackingCallbackUrl]=https://www.google.co.in/"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end
# response.code
# response.body
            

HTTP Response:

  • On success, the HTTP response status code will be 200
  • The Sid is the unique identifier of the SMS and it will be useful to log this for future debugging
  • the HTTP body will contain an XML similar to the one below
[
 {
    "SMSMessage": {
        "Sid": "0f477d60517e6e6a0f6d9a7e9af8630e",
        "AccountSid": "Exotel",
        "From": "0XXXXXX4890/WEBDEV",
        "To": "0XXXXX30240",
        "DateCreated": "2017-03-03 14:14:20",
        "DateUpdated": "2017-03-03 14:14:20",
        "DateSent": null,
        "Body": "Hello World one",
        "Direction": "outbound-api",
        "Uri": "/v1/Accounts/Exotel/SMS/Messages/0f477d60517e6e6a0f6d9a7e9af8630e.json",
        "ApiVersion": null,
        "Price": null,
        "Status": "queued",
        "DetailedStatusCode": 21010,
        "DetailedStatus": "PENDING_TO_OPERATOR", 
        "SmsUnits": null  
    }
 },
 {
    "SMSMessage": {
        "Sid": "1393e66deb633e7297bcfa9a9da0bb37",
        "AccountSid": "Exotel",
        "From": "0XXXXXX4890/WEBDEV",
        "To": "0XXXXX30241",
        "DateCreated": "2017-03-03 14:14:20",
        "DateUpdated": "2017-03-03 14:14:20",
        "DateSent": null,
        "Body": "Hello World two",
        "Direction": "outbound-api",
        "Uri": "/v1/Accounts/Exotel/SMS/Messages/1393e66deb633e7297bcfa9a9da0bb37.json",
        "ApiVersion": null,
        "Price": null,
        "Status": "queued",
        "DetailedStatusCode": 21010,
        "DetailedStatus": "PENDING_TO_OPERATOR",
        "SmsUnits": null     
    }        
 }
]
<?xml version="1.0" encoding="UTF-8"?>
<TwilioResponse>
 <SMSMessage>
  <Sid>0f477d60517e6e6a0f6d9a7e9af8630e</Sid>
  <AccountSid>Exotel</AccountSid>
  <From>0XXXXXX4890/WEBDEV</From>
  <To>XXXXX30240</To>
  <DateCreated>2017-03-03 14:14:20</DateCreated>
  <DateUpdated>2017-03-03 14:14:20</DateUpdated>
  <DateSent/>
  <Body>Hello World one</Body>
  <Direction>outbound-api</Direction>
  <Uri>/v1/Accounts/Exotel/SMS/Messages/0f477d60517e6e6a0f6d9a7e9af8630e</Uri>
  <ApiVersion/>
  <Price/>
  <Status>queued</Status>
  <DetailedStatusCode>21010</DetailedStatusCode>
  <DetailedStatus>PENDING_TO_OPERATOR</DetailedStatus>
  <SMSUnits/>
 </SMSMessage>
 <SMSMessage>
  <Sid>1393e66deb633e7297bcfa9a9da0bb37</Sid>
  <AccountSid>Exotel</AccountSid>
  <From>0XXXXXX4890/WEBDEV</From>
  <To>XXXXX30241</To>
  <DateCreated>2017-03-03 14:14:20</DateCreated>
  <DateUpdated>2017-03-03 14:14:20</DateUpdated>
  <DateSent/>
  <Body>Hello World two</Body>
  <Direction>outbound-api</Direction>
  <Uri>/v1/Accounts/Exotel/SMS/Messages/1393e66deb633e7297bcfa9a9da0bb37</Uri>
  <ApiVersion/>
  <Price/>
  <Status>queued</Status>
  <DetailedStatusCode>21010</DetailedStatusCode>
  <DetailedStatus>PENDING_TO_OPERATOR</DetailedStatus>
  <SMSUnits/>
 </SMSMessage>
</TwilioResponse>
curl -X POST https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend \
-d "From=0XXXXXX4890" \
-d "Messages[0][Body]=" \
-d "Messages[0][To]=XXXXX30240" \
-d "Messages[1][Body]=Hello World two" \
-d "Messages[1][To]=XXXXX30241" \
            
var request = require('request');

var dataString = 'From=0XXXXXX4890&Messages[0][Body]=&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241';

var options = {
    url: 'https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend',
    method: 'POST',
    body: dataString
};

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();
$data = array(
    'From' => '0XXXXXX4890',
    'Messages' => array(array('To' => 'XXXXX30240', 'Body' => ''), array('To' => 'XXXXX30241', 'Body' => 'Hello World two')),
);
$response = Requests::post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', $headers, $data);
            
import requests

data = {
  'From': '0XXXXXX4890',
  'Messages[0][Body]': '',
  'Messages[0][To]': 'XXXXX30240',
  'Messages[1][Body]': 'Hello World two',
  'Messages[1][To]': ' XXXXX30241'
}

requests.post('https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend', data=data)
            
require 'net/http'
require 'uri'

uri = URI.parse("https://<your_api_key>:<your_api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend")
request = Net::HTTP::Post.new(uri)
request.body = "From=0XXXXXX4890&Messages[0][Body]=&Messages[0][To]=XXXXX30240&Messages[1][Body]=Hello World two&Messages[1][To]=XXXXX30241"

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

# response.code
# response.body
            

HTTP Response (Partial Success):

  • On partial success i.e. where some of the messages in the bulk request succeeded but others did not, the HTTP response status code will be 207
  • The Sid is the unique identifier of the SMS (this will be available only for accepted requests), it will be useful to log this for future debugging
  • The HTTP body will contain a JSON / XML similar to the one below
[
    {
        "SMSMessage": {
            "Sid": null,
            "AccountSid": "Exotel",
            "From": null,
            "To": "0XXXXX30240",
            "DateCreated": null,
            "DateUpdated": null,
            "DateSent": null,
            "Body": "",
            "Direction": null,
            "Uri": null,
            "ApiVersion": null,
            "Price": null,
            "Status": "failed",
            "DetailedStatusCode": 23000,
            "DetailedStatus": "FAILED_MISSING_BODY"
            "SmsUnits": null
        }
    },
    {
        "SMSMessage": {
            "Sid": "1393e66deb633e7297bcfa9a9da0bb37",
            "AccountSid": "Exotel",
            "From": "0XXXXXX4890/WEBDEV",
            "To": "XXXXX30241",
            "DateCreated": "2017-03-03 14:14:20",
            "DateUpdated": "2017-03-03 14:14:20",
            "DateSent": null,
            "Body": "Hello World two",
            "Direction": "outbound-api",
            "Uri": "/v1/Accounts/exotel42us3/SMS/Messages/1393e66deb633e7297bcfa9a9da0bb37.json",
            "ApiVersion": null,
            "Price": null,
            "Status": "queued",
            "DetailedStatusCode": 21010,
            "DetailedStatus": "PENDING_TO_OPERATOR",
            "SmsUnits": null
        }
    }
]
<?xml version="1.0" encoding="UTF-8"?>
<TwilioResponse>
 <SMSMessage>
  <Sid/>
  <AccountSid>Exotel</AccountSid>
  <From/>
  <To>XXXXX30240</To>
  <DateCreated/>
  <DateUpdated/>
  <DateSent/>
  <Body></Body>
  <Direction/>
  <Uri/>
  <ApiVersion/>
  <Price/>
  <Status>failed</Status>
  <DetailedStatusCode>23000</DetailedStatusCode>
  <DetailedStatus>FAILED_MISSING_BODY</DetailedStatus>
  <SmsUnits/>
 </SMSMessage>
 <SMSMessage>
  <Sid>1393e66deb633e7297bcfa9a9da0bb37</Sid>
  <AccountSid>Exotel</AccountSid>
  <From>0XXXXXX4890/WEBDEV</From>
  <To>XXXXX30241</To>
  <DateCreated>2017-03-03 14:14:20</DateCreated>
  <DateUpdated>2017-03-03 14:14:20</DateUpdated>
  <DateSent/>
  <Body>Hello World!</Body>
  <Direction>outbound-api</Direction>
  <Uri>/v1/Accounts/Exotel/SMS/Messages/1393e66deb633e7297bcfa9a9da0bb37</Uri>
  <ApiVersion/>
  <Price/>
  <Status>queued</Status>
  <DetailedStatusCode>21010</DetailedStatusCode>
  <DetailedStatus>PENDING_TO_OPERATOR</DetailedStatus>
  <SmsUnits/>
 </SMSMessage>
</TwilioResponse>

Description of parameters mentioned in the above response:

Parameter Name

Type & Value

Sid

string; an alpha-numeric unique identifier of the SMS

AccountSid

String; Your account identifier

From

String; It is of format <VN>/<SenderID> where <VN> is your Exotel Virtual Number/ExoPhone through which you are sending the SMS. <SenderID> is the SenderID via which this SMS was sent

To

String; The mobile number(s) to which the SMS was sent

DateCreated

Time in format YYYY-MM-DD HH:mm:ss; The time when the SMS was received at our server

DateUpdated

Time in format YYYY-MM-DD HH:mm:ss; The time when any property of this SMS was last updated by our server

DateSent

Time in format YYYY-MM-DD HH:mm:ss; The time when the SMS was delivered to the recepient

Body

String; The body of the SMS message sent

Status

Can be of:

  • queued - This means that the SMS you have sent has been queued internally for delivery
  • sending - This means that we're in process of sending the SMS to upstream provider/gateway
  • submitted - This means that the SMS you have sent has been submitted from our system to SMS Gateway
  • sent - The SMS was successfully delivered to the handset
  • failed-dnd - The delivery of the SMS failed because the number belongs to the TRAI NCPR list. This is applicable only for promotional SMS
  • failed - The delivery of SMS failed. Please see DetailedStatusCode and DetailedStatus for further details.

DetailedStatus

Human readable word that explains what happened to the Message. Log these strings in your log files for grepping and debugging by a developer.

DetailedStatusCode

Exotel’s Detailed Status code corresponding to the DetailedStatus. Use this field to build decision making in your code.

Price

Double; If present, this will be the amount (in INR or USD) you have been charged for the SMS

Direction

  • incoming - incoming messages
  • outbound-api - messages initiated via the REST API
  • outbound-call - messages initiated during a call
  • outbound-reply - messages initiated in response to an incoming message

Uri

Uri is the path of the SmsSid

SmsUnits

 The number of  SMS units being sent

Mapping and Description of status codes

Detailed Status Code

Nature of Detailed Status Code

Status

DetailedStatus

What it means

21010

Intermediate, may change in future

queued

PENDING_TO_OPERATOR

The message is is being processed by Exotel.

21015

Intermediate, may change in future

sending

SENDING_TO_OPERATOR

The message has been processed by Exotel and is en-route to the operator.

21020

Intermediate, may change in future

submitted

PENDING_ON_OPERATOR

The message has been successfully Submitted to the operator and is pending delivery. In India, Promotional SMS may be in this state if submitted outside permitted time (10AM to 9PM).

20005

Final

sent

DELIVERED_TO_HANDSET

We know with confidence that the message has been delivered to recipient's handset.

20006

Final

sent

DELIVERED_TO_OPERATOR

The message has been delivered to operator. In some regions and routes, handset delivery status (DELIVERED_TO_HANDSET) is not available and hence this is the best we can ever report about the delivery status.

23005

Final

failed-dnd

FAILED_REJECTED_DND

The message has been rejected as the end user is a subscriber of DND (Do Not Disturb) services.

23010

Final

failed

FAILED_INVALID_DESTINATION_NUMBER

The destination number is incorrect, not SMS-enabled or is a PSTN landline.

23015

Final

failed

FAILED_SPAM_DETECTED

One of the most common reasons for SMS delivery failure is carrier level spam filters. Carriers have added systems and algorithms that detect spam content and then block these messages. Unfortunately, these filters are hidden, subject to carrier preferences, vary from carrier to carrier, and can be changed without notice.

23020

Final

failed

FAILED_REJECTED_BLACKLIST

You tried to send a message to a blacklisted phone number. That is, the user has already sent a STOP/DND opt-out message and no longer wishes to receive messages from you.

24990

Final

failed

FAILED_UNKNOWN_ERROR

Delivering your message failed for reasons that are unknown to us and to our carriers. If you notice too many of these cases, please reach out to us.

23030

Final

failed

FAILED_UNAVAILABLE_ROUTE

The carrier and fallback carriers were not able to deliver the SMS message because no route was available.

23035

Final

failed

FAILED_SUBSCRIBER_UNAVAILABLE

This message was not delivered because subscriber was temporarily unavailable. For example, the receiving handset was out of coverage or switched off. This is a temporary failure, but a message sent to the same subscriber at a later point in time may get delivered.

23040

Final

failed

FAILED_SUBSCRIBER_UNKNOWN

Subscriber is unknown to the operators or no longer active.

23050

Final

failed

FAILED_EXPIRED

The message was sent to the operator and may have been retried several times within the default network SMS expiration duration. The message request has now expired.

23060

Final

failed

FAILED_REJECTED

For a number of reasons, the message was rejected by Exotel or the operator.

24105

Final

failed

FAILED_HANDSET_ERROR

The message was not delivered to the subscriber due to handset failure

24110

Final

failed

FAILED_OPERATOR_ERROR

The message failed due to an issue at the operator end

23070

Final

failed

FAILED_INVALID_MESSAGE

The message was rejected by the operator as Invalid. While Exotel will automatically split messages longer than 160 GSM 7-bit characters, or 70 unicode 16-bit characters into multipart SMS, Messages exceeding the allowed character limit of 2000 characters may also end in this state. Any request error related to the message, say unindentified character, may also fall under this bucket.

In India, if DLT related parameters are not set like Entity ID, your SMS may fail with this error code.

23072

Final

failed

FAILED_INVALID_SENDER_ID

 

The message failed due to invalid or unregistered Sender ID. In case of India, if your Sender ID (header) is not registered with operator DLT platform, you may receive this error.

24010

Final

failed

FAILED_SYSTEM_ERROR

SMS failed while processing within Exotel system.

24120

Final

failed

FAILED_SUBSCRIBER_ERROR

All subscriber or recipeient issues that are unrelated to the handset (For ex - Receiver does not have enough mobile balance to receive the SMS) may fall under this bucket.

23080

Final

failed

SENDER_BLOCKED_BY_DLT

Applicable only for SMSes sent to Indian destination numbers via domestic lines. Sender ID (Header) is blocked or failed at DLT platform by the operator due to mismatch, non-registration, template not linked with Sender (header) etc.

*This DetailedStatus will reflect in API from 17th May 2021

23081

Final

failed

ENTITY_BLOCKED_BY_DLT

Applicable only for SMSes sent to Indian destination numbers via domestic lines. Entity (DLT Entity ID) is blocked or failed at DLT platform by the operator due to DLT Entity ID not passed in API or configured on Exotel Dashboard, values are mismatching etc.

*This DetailedStatus will reflect in API from 17th May 2021

23082

Final

failed

TEMPLATE_BLOCKED_BY_DLT

Applicable only for SMSes sent to Indian destination numbers via domestic lines. Template (Template ID) is blocked or failed at DLT due to Template ID not set in API or configured on Exotel Dashboard, content is not exactly matching, non-registeration of the template etc.

*This DetailedStatus will reflect in API from 17th May 2021

23083

Final

failed

FAILED_DLT_SCRUBBING_ERROR

Applicable only for SMSes sent to Indian destination numbers via domestic lines. SMS is blocked or failed at DLT even after registration due to explicit blocking of the Sender ID due to spam, issues with consent or any other technical issues with DLT platform.

*This DetailedStatus will reflect in API from 17th May 2021

23181

Final

failed

DLT_TEMPLATE_ID_INVALID

Applicable only for SMS sent to Indian destination numbers via domestic lines. This Template is invalid.

Some operators may report this error as 23182: DLT_TEMPLATE_NOT_FOUND

23182

Final

failed

DLT_TEMPLATE_NOT_FOUND

Applicable only for SMS sent to Indian destination numbers via domestic lines. This Template was not found.

23183

Final

failed

DLT_TEMPLATE_ID_INACTIVE

Applicable only for SMS sent to Indian destination numbers via domestic lines. This Template is inactive.

23184

Final

failed

DLT_TEMPLATE_ID_BLACKLISTED

Applicable only for SMS sent to Indian destination numbers via domestic lines. This Template has been blacklisted. This may happen due to users reporting this message.

23185

Final

failed

DLT_TEMPLATE_DOES_NOT_MATCH

Applicable only for SMS sent to Indian destination numbers via domestic lines. The message body does not match the Template on the DLT portal.

23186

Final

failed

DLT_LENGTH_EXCEEDED

Applicable only for SMS sent to Indian destination numbers via domestic lines. The message has exceeded the maximum allowed length of 2000 characters.

Some operators may report this error as 23185: DLT_TEMPLATE_DOES_NOT_MATCH

23281

 

Final

failed

DLT_ENTITY_NOT_FOUND

Applicable only for SMS sent to Indian destination numbers via domestic lines. The ENTITY_ID was not found on the DLT portal.

Some operators may report this error as 23081: ENTITY_BLOCKED_BY DLT. 

Mapping and Description of HTTP API Error Codes in the API response

POST (/send, /bulksend) API error codes:

Scenario

HTTP Error Code

API Error code

Error message

If your trial account is being used to send promotional SMS

403

40000

Not allowed to send promotional SMS(s).

If account is trial and KYC not completed, and one of the following occurs:

- Number not whitelisted

- It is whitelisted but is not of type agent-whitelist

403

340030

Your account is not yet KYC compliant;

If there is insufficient balance in your account

403

40001

Insufficient balance to send $n sms. Please recharge your account.

If account is not configured to send SMSes to the recipient country.

403

40003

Your account is not configured to send SMSes to this country. Please write to hello@exotel.com to update the setup.

If yours is a trial account with incomplete KYC and has a whitelisting error. Email hello@exotel.com for more details.

500

35000

Internal Server Error

Exotel internal error code related to processing. Email hello@exotel.com for more details.

500

40100

Error Processing Request

Message body for single send is invalid on account of it being empty/missing

400

40200

Message body cannot be empty.

Message body for bulk send is invalid on account of it being empty/missing

400

40201

Invalid parameters: Messages is a mandatory field

Invalid (Array) message body

400

40202

Message body is invalid.

If all destination numbers are invalid

400

40203

All the destination numbers are invalid: $number

Invalid SMS type parameter in request

400

40204

Invalid parameters: SmsType is not set correctly

Invalid (Empty) From parameter in request

400

40205

Empty From field in the request

From parameter does not match SMS type

400

40206

Invalid parameters: From format is not matching with the SmsType

Request parameter passed as array and not as a string

400

40207

Array passed as Value in params. Expecting String

Invalid (Non-array) messages parameter

400

40208

Invalid parameters: Messages has to be an array

Invalid encoding type parameter in SMS request

400

40209

Encoding type is not properly set. Please check the encoding type again before sending the request for Msg=[$body]

Missing FROM parameter in SMS request

400

40210

Invalid parameters: From is a mandatory field

If all the below conditions are true:

- SMS type is promotional

- It is an Indian account

- Promotional sender ID is not found (contact hello@exotel.com)

400

40300

No transactional template found and no numeric sender ID exists in your account for sending it as promotional

If your sender ID is not found This is specific to international accounts and SMS type is not promotional

400

40301

No transactional sender ID found in your account

More than 100 SMSs in a dynamic bulk request

400

40400

Not more than 100 SMSs are allowed in one API request.

If your account has sent POST requests higher than the maximum limit feasible

429

40402

Too many POST requests.

In the trial phase, if your account exceeds the max. SMS limit

429

40404

Please note that you can send only 10 SMS from your account during the trial phase.

Throttle limit has been exceeded

(Update to existing error code)

503

35006 -> 40405

Service Unavailable

More than 100 SMSs in a static bulk request

400

40406

Not more than 100 SMSs are allowed in one API request.

POST API call to an unrecognized SMS endpoint. eg: v1/Accounts/<account-sid>/Sms/<invalid-parameter>

405

40502

This method is not supported

POST (/send, /bulksend) and /GET (/sms) error codes:

Scenario

HTTP Error Code

API Error code

Error message

If your account is inactive

403

40002

Account inactive.

Api call to v1/Accounts/exotel42us3/Sms

400

40500

Invalid Parameters

Unsupported API version

400

 

Exotel API Version $version not supported. Contact Exotel for details.

Accounts missing from URL

400

 

/Accounts/ missing from URL

Account sid missing from URL

403

34009

Action forbidden on given resource;

Auth key or auth token missing

401

 

Authentication is required to view this page.

Invalid auth key or auth token

401

34010

Unauthorized;

Invalid Account sid or any resource or action is missing or invalid

403

34009

Action forbidden on given resource;

Non alpha-numeric auth key or token

400

34001

Bad or missing parameters in request.;