Skip to main content

Creating an SMS Campaign

This guide walks you through the complete process of creating a bulk SMS campaign on Exotel, from DLT template preparation to launching and monitoring your campaign.

Prerequisites​

Before creating an SMS campaign, ensure you have:

  • An active Exotel account with API access enabled
  • Your API key and API token (available in Dashboard > Settings > API)
  • A registered DLT Entity ID (required for SMS in India)
  • At least one approved DLT template (with Template ID)
  • An approved Sender ID (alphabetical for transactional, numeric for promotional)
  • A contact list in CSV format or existing contact list SIDs
info

DLT (Distributed Ledger Technology) registration is mandatory for sending SMS in India. All SMS must use pre-approved templates registered with your DLT portal. For DLT setup details, see DLT Compliance.

Step 1: Register Your DLT Template​

Before you can use a message in a campaign, it must be registered and approved on your DLT portal.

Template Registration Process​

  1. Log in to your DLT portal (Jio, Airtel, Vodafone-Idea, or BSNL)
  2. Navigate to Templates > Add Template
  3. Select the template type:
    • Transactional -- OTPs, order updates, alerts (can be sent 24/7)
    • Promotional -- Marketing offers, promotions (restricted to 9 AM -- 9 PM)
    • Service Implicit -- Existing customer communications
    • Service Explicit -- Communications with explicit consent
  4. Enter your message content with variables marked as {#var#}
  5. Submit for approval (typically takes 1-3 business days)

Template Example​

DLT template:

Dear {#var#}, your order {#var#} has been shipped. Track at {#var#}. Thank you for shopping with {#var#}.

Exotel campaign message (using CSV column headers):

Dear @@first_name, your order @@order_id has been shipped. Track at @@tracking_url. Thank you for shopping with @@company_name.

For complete template management details, see SMS Campaign Templates.

Step 2: Prepare Your Contact List​

CSV Format for SMS Campaigns​

number,first_name,order_id,tracking_url,company_name
+919876543210,Rahul,ORD-2024-001,https://track.example.com/001,Acme Store
+919876543211,Priya,ORD-2024-002,https://track.example.com/002,Acme Store
+919876543212,Amit,ORD-2024-003,https://track.example.com/003,Acme Store
ColumnRequiredDescription
numberYesRecipient phone number in E.164 format
Custom columnsFor dynamic campaignsAny columns referenced by @@variable in your message template

Upload the Contact List​

curl -X POST "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/contacts/csv-upload" \
-F "list_name=Order_Shipment_Feb" \
-F "file_name=@contacts.csv" \
-F "type=static"

For dynamic (personalized) campaigns, set type=dynamic:

curl -X POST "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/contacts/csv-upload" \
-F "list_name=Personalized_Shipment_Feb" \
-F "file_name=@contacts.csv" \
-F "type=dynamic"
tip

Verify the upload is complete by checking the upload status endpoint before creating your campaign. See Contact List Management for detailed upload instructions.

Step 3: Configure Campaign Settings​

Essential Parameters​

ParameterRequiredDescription
listsYesArray of contact list SIDs
sender_idYesApproved Sender ID (e.g., EXOTL for transactional)
sms_typeYestrans (transactional) or promo (promotional)
dlt_entity_idYesYour DLT Entity ID
dlt_template_idYesApproved DLT Template ID for this message
bodyYesMessage content matching the DLT template
nameNoCampaign name for identification
campaign_typeNostatic (same message) or dynamic (personalized)

Sender ID Types​

TypeFormatExampleUse Case
Alphabetical (6 chars)Letters onlyEXOTLTransactional, service messages
NumericNumbers567890Promotional campaigns
warning

Your Sender ID must be registered with your DLT portal and approved before use. Using an unregistered Sender ID will cause all messages to fail delivery.

Static vs. Dynamic Campaigns​

Static campaigns send the identical message to all recipients:

{
"lists": ["list_sid_1", "list_sid_2"],
"body": "Your subscription renewal is due. Please visit our website to renew. Thank you.",
"campaign_type": "static"
}
  • Supports up to 5 contact lists
  • Maximum 1,00,000 contacts per list
  • All recipients receive the same message

Dynamic campaigns personalize the message for each recipient using CSV column values:

{
"lists": ["list_sid_1"],
"body": "Dear @@first_name, your order @@order_id has been shipped. Track at @@tracking_url.",
"campaign_type": "dynamic"
}
  • Supports 1 contact list only
  • Maximum 5,00,000 contacts
  • Each recipient gets a personalized message

Step 4: Set the Schedule​

Immediate Send​

Omit the schedule object to send messages immediately:

{
"lists": ["list_sid_1"],
"body": "Your OTP is 123456. Valid for 5 minutes.",
"sender_id": "EXOTL",
"sms_type": "trans"
}

Scheduled Send​

"schedule": {
"send_at": "2024-02-15T10:00:00+05:30",
"end_at": "2024-02-15T18:00:00+05:30"
}
ParameterFormatDescription
send_atRFC 3339When to start sending messages
end_atRFC 3339When to stop sending (remaining contacts are paused)
warning

SMS campaigns must have a minimum 10-minute lead time. The send_at time must be at least 10 minutes in the future from the time of campaign creation.

Scheduling Rules for SMS Types​

SMS TypeAllowed HoursNotes
Transactional24/7No time restrictions
Promotional9:00 AM -- 9:00 PM ISTTRAI regulation; messages outside this window will be queued
Service Implicit24/7Subject to DLT category rules
Service Explicit24/7Subject to DLT category rules

Step 5: Configure Callbacks​

Set up webhook URLs to receive delivery status updates:

"status_callback": "https://your-server.com/webhooks/sms-campaign-status",
"sms_status_callback": "https://your-server.com/webhooks/sms-delivery"
CallbackFires WhenData Included
sms_status_callbackEach individual SMS delivery status changesTo number, delivery status, timestamp, SmsSid
status_callbackCampaign status changes (completed, paused)Campaign stats, completion summary

Step 6: Launch the Campaign​

Combine all settings into the API request:

curl -X POST "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/sms-campaigns" \
-H "Content-Type: application/json" \
-d '{
"lists": ["list_sid_1"],
"sender_id": "EXOTL",
"sms_type": "trans",
"dlt_entity_id": "1234567890123456789",
"dlt_template_id": "9876543210123456789",
"body": "Dear @@first_name, your order @@order_id has been shipped. Track at @@tracking_url. Thank you for shopping with Acme Store.",
"name": "Order Shipment Notifications Feb",
"campaign_type": "dynamic",
"schedule": {
"send_at": "2024-02-15T10:00:00+05:30",
"end_at": "2024-02-15T18:00:00+05:30"
},
"sms_status_callback": "https://your-server.com/webhooks/sms-delivery",
"status_callback": "https://your-server.com/webhooks/sms-campaign-status"
}'

Successful response:

{
"response": [{
"code": 200,
"status": "success",
"data": {
"id": "sms_camp_xyz789",
"name": "Order Shipment Notifications Feb",
"status": "Created",
"stats": {
"total": 3000,
"sent": 0,
"delivered": 0,
"failed": 0,
"pending": 3000
}
}
}]
}

API Reference: See the SMS Campaigns API for complete endpoint documentation.

Step 7: Monitor and Manage​

Check Campaign Status​

curl "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/sms-campaigns/<campaign_id>"

Pause the Campaign​

curl -X PUT "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/sms-campaigns/<campaign_id>" \
-H "Content-Type: application/json" \
-d '{"action": "pause"}'

Resume a Paused Campaign​

curl -X PUT "https://<api_key>:<api_token>@api.exotel.com/v2/accounts/<account_sid>/sms-campaigns/<campaign_id>" \
-H "Content-Type: application/json" \
-d '{"action": "resume"}'

SMS Delivery Throughput​

SettingDefaultDescription
SMS capacity300 SMS/minuteDefault account throughput
Throttle modeautoUses full account capacity
Custom throttleSet via throttle parameterLimit to specific SMS/minute rate
info

If you need higher throughput than 300 SMS/minute, contact Exotel support to increase your account capacity. Enterprise plans support up to several thousand SMS per minute.

Complete Configuration Reference​

ParameterRequiredDefaultDescription
listsYes--Array of contact list SIDs
sender_idYes--Approved DLT Sender ID
sms_typeYes--trans or promo
dlt_entity_idYes--DLT Entity ID
dlt_template_idYes--Approved DLT Template ID
bodyYes--Message content (must match DLT template)
nameNoAuto-generatedCampaign name
campaign_typeNostaticstatic or dynamic
scheduleNoImmediateSchedule object with send_at and end_at
sms_status_callbackNo--Per-SMS delivery webhook URL
status_callbackNo--Campaign-level webhook URL
throttleNoAccount limitSMS/minute rate

Troubleshooting​

IssueCauseSolution
All SMS failing with DLT errorTemplate ID or Entity ID mismatchVerify DLT credentials match your registered values
Message body rejectedBody does not match registered templateEnsure variables and static text match the DLT template exactly
Promotional SMS not deliveredSent outside 9 AM -- 9 PM windowSchedule within allowed promotional hours
Low delivery rateDND-registered recipientsCheck DND filtering; consider transactional category if applicable
Campaign stuck in CreatedSchedule send_at is in the futureWait for the scheduled time or update the schedule
Dynamic variables showing raw textColumn header mismatchVerify CSV column headers match @@variable names exactly

Next Steps​