What gets generated
SMS sending with opt-in enforcement
# app/services/sms_service.py
def send_sms(to_phone, body, override_optin=False):
if not override_optin:
consent = SmsConsent.query.filter_by(phone=to_phone, opted_in=True).first()
if not consent:
logger.warning("SMS skipped: no opt-in for %s", to_phone)
return False
if SmsSuppression.query.filter_by(phone=to_phone).first():
logger.info("SMS suppressed: %s", to_phone)
return False
try:
msg = twilio_client.messages.create(
from_=current_app.config["TWILIO_FROM_NUMBER"],
to=to_phone,
body=body,
status_callback=current_app.config["TWILIO_STATUS_CALLBACK_URL"],
)
SmsLog(phone=to_phone, message_sid=msg.sid, status="queued").save()
return True
except TwilioRestException as e:
logger.error("Twilio failed: to=%s err=%s", to_phone, e)
return False
Opt-in / opt-out tracking
The SmsConsent model tracks who opted in, when, where, and the message they received at opt-in (TCPA evidence). The SmsSuppression model tracks STOP / UNSUBSCRIBE / END / QUIT keywords arriving via the inbound webhook.
Delivery webhooks
Twilio's status callback is wired to a route that updates the SmsLog row: queued → sent → delivered or failed. Failed messages with retryable error codes trigger the fallback channel.
Fallback to email
When SMS fails (number invalid, MNO outage, undeliverable region), the generated notification_dispatcher.py falls back to email. The fallback is logged so you can see SMS-channel reliability over time.
Regional handling
For numbers in regulated regions, generated code checks the country code and applies the right sender ID convention. India: 6-character alphanumeric registered sender. UK: shortcode or alphanumeric. Africa: alphanumeric (must be pre-registered with each MNO).
What ships in docs/
docs/decisions/ADR-0011-sms-provider-twilio.md— why Twilio over MessageBird / Vonage, with rejected alternativesdocs/compliance/tcpa-controls.md— when targeting US numbers, the explicit opt-in evidence flowdocs/runbooks/sms-deliverability.md— what to check when messages aren't landing (sender registration, opt-in records, MNO outage check)
Environment variables generated
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
TWILIO_FROM_NUMBER=+1... # or alphanumeric sender ID per region
TWILIO_STATUS_CALLBACK_URL=https://your-domain.com/api/webhooks/twilio/status
Twilio documentation references
Internal links
- SendGrid integration for the email fallback
- Booking use case for SMS reminder flows
CTA
Try it — free plan, no credit card. archiet.com.
Generate a codebase with Twilio wired and the opt-in / opt-out tracking, decide if it's the regulatory shape you'd ship.