Skip to main content

Bulk SMS

Send the same message to multiple recipients, or unique messages to different recipients in a single API call.


Static Bulk SMS (Same Message)​

Send an identical message to multiple phone numbers in one request. Uses the same endpoint as Send SMS — pass To as a repeated array parameter.

Parameters​

All Send SMS parameters apply. The key difference is To, which must be passed as an array:

ParameterRequiredDescription
FromMandatoryExoPhone or approved Sender ID
To[]MandatoryRepeat this parameter for each recipient number
BodyMandatoryMessage content (max 2000 characters)

Examples​

curl -X POST https://<api_key>:<api_token><subdomain>/v1/Accounts/<your_sid>/Sms/send \
-d "From=0XXXXXX4890" \
-d "To[]=+919876543210" \
-d "To[]=+919876543211" \
-d "Body=Flash sale! 50% off all items today." \
-d "DltEntityId=1234567890"

URL Shortening Example​

curl -X POST https://<api_key>:<api_token><subdomain>/v1/Accounts/<your_sid>/Sms/send \
-d "From=0XXXXXX4890" \
-d "To[]=+919876543210" \
-d "To[]=+919876543211" \
-d "Body=Sale at https://example.com/sale" \
-d "ShortenUrl=true" \
-d "ShortenUrlParams[Header]=EXOTEL" \
-d "ShortenUrlParams[Tracking]=true" \
-d "ShortenUrlParams[ClickTrackingCallbackUrl]=https://your-server.com/clicks"

Response​

Success (HTTP 200): Returns an array of SMSMessage objects, one per recipient.

[
{
"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": "Flash sale! 50% off all items today.",
"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
}
}
]

Partial success (HTTP 207): Returned when some recipients succeeded and others failed. Failed entries have "Status": "failed" and null Sid.

[
{
"SMSMessage": {
"Sid": null,
"AccountSid": "Exotel",
"From": null,
"To": null,
"DateCreated": null,
"DateUpdated": null,
"DateSent": null,
"Body": "Flash sale! 50% off all items today.",
"Direction": null,
"Uri": null,
"ApiVersion": null,
"Price": null,
"Status": "failed",
"SmsUnits": null,
"DetailedStatusCode": 23010,
"DetailedStatus": "FAILED_INVALID_DESTINATION_NUMBER"
}
},
{
"SMSMessage": {
"Sid": "1393e66deb633e7297bcfa9a9da0bb37",
"AccountSid": "Exotel",
"From": "0XXXXXX4890/WEBDEV",
"To": "+919876543211",
"DateCreated": "2017-03-03 14:14:20",
"DateUpdated": "2017-03-03 14:14:20",
"DateSent": null,
"Body": "Flash sale! 50% off all items today.",
"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
}
}
]

Dynamic Bulk SMS (Unique Messages)​

Send personalized messages to different recipients in a single request. Uses the /bulksend endpoint with form-encoded Messages[] array. Maximum 100 messages per request.

Parameters​

ParameterRequiredDescription
FromOptionalDefault ExoPhone or Sender ID. Used when From is not set in a Messages entry.
MessagesMandatoryArray of message objects (max 100). Each object must include To and Body.
Messages[N][To]MandatoryRecipient number for message N
Messages[N][Body]MandatoryMessage content for message N (max 2000 chars)
Messages[N][From]OptionalPer-message Sender ID; falls back to outer From
Messages[N][SmsType]OptionalPer-message SMS type: transactional, transactional_opt_in, promotional
Messages[N][DltTemplateId]OptionalPer-message DLT Template ID (India)
EncodingTypeOptionalplain or unicode
ShortenUrlOptionaltrue to shorten URLs
ShortenUrlParams[Header]OptionalDLT-registered header for the short URL domain
ShortenUrlParams[Tracking]Optionaltrue to enable click tracking
ShortenUrlParams[ClickTrackingCallbackUrl]OptionalWebhook URL for click events
StatusCallbackOptionalURL to receive delivery status per message
DltEntityIdOptional (Mandatory for India)DLT Entity ID applied to all messages
CustomFieldOptionalCustom reference field
PriorityOptionalnormal or high

Examples​

curl -X POST https://<api_key>:<api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend \
-d "From=0XXXXXX4890" \
-d "Messages[0][Body]=Hi Rahul, your order #1234 has shipped." \
-d "Messages[0][To]=+919876543210" \
-d "Messages[1][Body]=Hi Priya, your order #5678 has shipped." \
-d "Messages[1][To]=+919876543211"

URL Shortening Example​

curl -X POST https://<api_key>:<api_token><subdomain>/v1/Accounts/<your_sid>/Sms/bulksend \
-d "From=0XXXXXX4890" \
-d "Messages[0][Body]=Hi Rahul, your deal: https://example.com/deal/1234" \
-d "Messages[0][To]=+919876543210" \
-d "Messages[1][Body]=Hi Priya, your deal: https://example.com/deal/5678" \
-d "Messages[1][To]=+919876543211" \
-d "ShortenUrl=true" \
-d "ShortenUrlParams[Header]=EXOTEL" \
-d "ShortenUrlParams[Tracking]=true" \
-d "ShortenUrlParams[ClickTrackingCallbackUrl]=https://your-server.com/clicks"

Response​

Success (HTTP 200):

[
{
"SMSMessage": {
"Sid": "0f477d60517e6e6a0f6d9a7e9af8630e",
"AccountSid": "Exotel",
"From": "0XXXXXX4890/WEBDEV",
"To": "+919876543210",
"DateCreated": "2017-03-03 14:14:20",
"DateUpdated": "2017-03-03 14:14:20",
"DateSent": null,
"Body": "Hi Rahul, your order #1234 has shipped.",
"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": "+919876543211",
"DateCreated": "2017-03-03 14:14:20",
"DateUpdated": "2017-03-03 14:14:20",
"DateSent": null,
"Body": "Hi Priya, your order #5678 has shipped.",
"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
}
}
]

Partial success (HTTP 207): Some messages failed. Failed entries have "Status": "failed" with a DetailedStatusCode and null Sid.

[
{
"SMSMessage": {
"Sid": null,
"AccountSid": "Exotel",
"From": null,
"To": "+919876543210",
"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": "+919876543211",
"DateCreated": "2017-03-03 14:14:20",
"DateUpdated": "2017-03-03 14:14:20",
"DateSent": null,
"Body": "Hi Priya, your order #5678 has shipped.",
"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
}
}
]

Limits​

LimitValue
Max recipients — static bulk100 numbers
Max messages — dynamic bulk100 messages
API error code40406 (static) / 40400 (dynamic) if exceeded
note

Each message in a bulk request is processed independently. Individual messages may succeed or fail without affecting others.

Try It​