Twilio Send SMS — Sending Text Messages with the Programmable SMS API
In this tutorial, you will learn about Twilio Send SMS. We cover key concepts, practical examples, and best practices to help you master this topic.
Twilio Programmable SMS API allows you to send text messages worldwide from your application using a Twilio phone number, with delivery tracking, error handling, and support for long messages through automatic segmentation.
What You'll Learn
- How to send SMS messages with the Twilio API
- How to track delivery status with status callbacks
- How to handle message errors and failures
Why It Matters
Sending SMS directly from your application requires carrier agreements, regulatory Compliance (10DLC, A2P), and infrastructure for handling delivery receipts. Twilio abstracts all of this behind a simple API, handling carrier negotiations, delivery receipts, and compliance automatically.
Real-World Use
DodaTech sends SMS notifications for: login verification codes, payment confirmations, shipment tracking updates, and security alerts. Each message includes a status callback URL so the system can track delivery, detect failures, and retry if needed.
from twilio.rest import Client
TWILIO_ACCOUNT_SID = 'your_account_sid'
TWILIO_AUTH_TOKEN = 'your_auth_token'
TWILIO_PHONE_NUMBER = '+15551234567'
client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)
def send_sms(to_number, message_body):
message = client.messages.create(
body=message_body,
from_=TWILIO_PHONE_NUMBER,
to=to_number
)
print(f"Message sent: {message.sid}")
print(f"Status: {message.status}")
return message.sid
# Send a message
send_sms('+15559876543', 'Your verification code is: 847291')
Expected output:
Message sent: SMabc123def456ghi789jkl
Status: queued
Status Callbacks
def send_sms_with_tracking(to_number, message_body):
message = client.messages.create(
body=message_body,
from_=TWILIO_PHONE_NUMBER,
to=to_number,
status_callback='https://api.dodatech.com/twilio/sms-status',
provide_feedback=True
)
# Store the message SID for tracking
database.store_message_sid(
sid=message.sid,
to_number=to_number,
message=message_body
)
return message.sid
@app.route('/twilio/sms-status', methods=['POST'])
def sms_status_webhook():
message_sid = request.form.get('MessageSid')
message_status = request.form.get('MessageStatus')
# Possible statuses: queued, sent, delivered, failed, undelivered
database.update_message_status(message_sid, message_status)
if message_status == 'delivered':
print(f"Message {message_sid} delivered successfully")
elif message_status in ('failed', 'undelivered'):
error_code = request.form.get('ErrorCode')
print(f"Message {message_sid} failed: {error_code}")
# Trigger retry logic
retry_failed_message(message_sid)
elif message_status == 'sent':
print(f"Message {message_sid} sent to carrier")
return '', 200
Error Handling
from twilio.base.exceptions import TwilioRestException
def send_sms_safe(to_number, message_body):
try:
message = client.messages.create(
body=message_body,
from_=TWILIO_PHONE_NUMBER,
to=to_number
)
return {'success': True, 'sid': message.sid}
except TwilioRestException as e:
error_map = {
21211: 'Invalid phone number',
21608: 'Account not authorized to call this number',
21610: 'Message body is required',
21611: 'Message body exceeds 1600 characters',
21612: 'Number is not SMS capable',
21614: 'Number is unverified',
21617: 'Message too long for carrier'
}
error_msg = error_map.get(e.code, f'Twilio error {e.code}: {str(e)}')
print(f"SMS failed: {error_msg}")
return {'success': False, 'error': error_msg}
except Exception as e:
print(f"Unexpected error sending SMS: {e}")
return {'success': False, 'error': str(e)}
Common Mistakes
1. Not Validating Phone Numbers
Invalid phone numbers cause API errors. Use the Twilio Lookup API to validate numbers before sending.
2. Forgetting to Handle Status Callbacks
Without status callbacks, you cannot detect delivery failures. Always set a status_callback URL.
3. Sending Messages Over 160 Characters
Single SMS segments are 160 characters. Longer messages are split. Use body up to 1600 characters for automatic segmentation.
4. Not Testing with Trial Account Numbers
Trial accounts can only send to verified numbers. Use a production account or verify numbers for testing.
5. Ignoring Regulatory Compliance
SMS requires 10DLC registration for US numbers, opt-in consent, and proper message formatting. Non-compliance leads to carrier filtering.
Practice Questions
- What Twilio class is used to send SMS?
- What parameter tracks delivery status?
- What is the maximum message body length?
- What error code indicates an invalid phone number?
- How do you handle delivery failures?
Answers
client.messages.create(). 2.status_callbackURL parameter. 3. 1600 characters (auto-segmented). 4. 21211. 5. Implement a status_callback Webhook and retry logic on failed/undelivered status.
Challenge
Build an SMS notification service with: phone number validation via Twilio Lookup, message sending with status callbacks, delivery tracking in a database, automatic retry for failed messages (up to 3 attempts with backoff), and a dashboard showing delivery stats.
FAQ
Mini Project
Build a complete SMS notification system with: phone number validation, message sending with delivery tracking, status callback webhook handler, automatic retry logic with exponential backoff, delivery analytics dashboard, and support for message templates with dynamic variables.
What's Next
- Learn about receiving SMS via Webhooks
- Explore Twilio Messaging Service for advanced features
- Continue to Twilio Verify for phone verification
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro