Back to Blog
Integration Guides

How to Send SMS with Twilio and Flask: Step-by-Step Tutorial

Integrate Twilio SMS into your Flask application using the Twilio Python library with Blueprint-based route organisation and webhook support.

DA
Danial A
Senior Twilio Consultant, Telphi Consulting
June 22, 2026
7 min read
Twilio
Integration
SDK
Mobile
How to Send SMS with Twilio and Flask: Step-by-Step Tutorial

Twilio SMS and Flask integrate through the Twilio Python helper library installed with pip install twilio, with credentials stored in Flask's application config loaded from environment variables, service functions for dispatch logic, and Blueprint-organized routes for SMS sending and inbound webhook handling. This integration is used by Python developers building Flask microservices, REST APIs, or web applications that need to dispatch SMS for OTP codes, alert notifications, form submission confirmations, or booking reminders, and who want a lightweight Python integration that fits Flask's minimal, explicit configuration philosophy without the overhead of a full framework. The Twilio client is instantiated with credentials from flask.current_app.config, SMS is dispatched from service functions imported in Blueprint views, and inbound Twilio webhooks are handled by a Blueprint route that returns TwiML XML using the twilio Python library's MessagingResponse builder.

What You Need Before You Start

Install dependencies by running pip install twilio flask python-dotenv and add them to requirements.txt. Create a .env file at the Flask project root with TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_FROM_NUMBER. In your Flask application factory function, load the .env file with load_dotenv() called before create_app, and set app.config['TWILIO_ACCOUNT_SID'] = os.environ.get('TWILIO_ACCOUNT_SID'), app.config['TWILIO_AUTH_TOKEN'] = os.environ.get('TWILIO_AUTH_TOKEN'), and app.config['TWILIO_FROM_NUMBER'] = os.environ.get('TWILIO_FROM_NUMBER') inside create_app. Add a startup assertion that raises RuntimeError if any config value is None. Provision a Twilio SMS-capable phone number and collect credentials from the Twilio Console.

Step-by-Step Integration Guide

Create a service module at app/services/twilio_service.py that imports Client from twilio.rest and current_app from flask, and defines a send_sms(to, body) function that instantiates client = Client(current_app.config['TWILIO_ACCOUNT_SID'], current_app.config['TWILIO_AUTH_TOKEN']), calls message = client.messages.create(to=to, from_=current_app.config['TWILIO_FROM_NUMBER'], body=body), and returns message.sid. Wrap the create call in try/except catching twilio.base.exceptions.TwilioRestException, log with current_app.logger.error, and raise or return None. Create a Flask Blueprint at app/blueprints/sms.py, define a POST /send route that calls request.get_json(), extracts to and body, calls send_sms, and returns jsonify with the sid on success or a 500 error JSON on exception. Define a POST /webhook route that imports MessagingResponse from twilio.twiml.messaging_response, constructs resp = MessagingResponse(), adds resp.message('Reply text'), and returns Response(str(resp), mimetype='text/xml'). Register the Blueprint in create_app with app.register_blueprint(sms_bp, url_prefix='/sms').

Common Issues and How to Fix Them

The send_sms function raises RuntimeError 'Working outside of application context' when called from a background thread or Celery task that does not have an active Flask application context, because current_app is a context-local proxy that requires an active context to resolve. Use the with app.app_context() context manager when calling Twilio functions from background threads, or pass the Flask app instance to the service function rather than relying on current_app. The webhook Blueprint route returns HTTP 400 when Twilio posts to it because Flask's CSRF protection from Flask-WTF is active globally and rejects the Twilio POST without a CSRF token. Exempt the webhook route from CSRF using csrf.exempt(sms_bp) if using Flask-WTF's CSRF extension, and add Twilio signature validation using twilio.request_validator.RequestValidator to replace CSRF protection with Twilio's own request authentication. The /send route returns a 404 when the Blueprint is registered with a url_prefix but the client requests /send without the prefix. Verify the registered prefix matches the request URL, test by running flask routes to list all registered routes, and adjust the client's request URL to include the /sms prefix.

How to Get More from This Integration

Add Celery async SMS dispatch to Flask by creating a Celery task in a tasks module that accepts to and body strings, calls send_sms within an app.app_context() block, and handles retries with self.retry on TwilioRestException, then calling send_sms_task.delay(to, body) from Blueprint routes so the HTTP response returns immediately while Celery processes the Twilio API call in a worker. Build a Twilio Verify two-factor authentication flow in Flask by adding /verify/send and /verify/check Blueprint routes, calling verify.v2.services(sid).verifications.create in the send route and verificationChecks.create in the check route, storing the verified status in Flask-Login's user session on an approved result, and adding a login_required decorator variant that also requires phone_verified in the session. Implement webhook signature validation as a Flask decorator by writing a require_twilio_signature function that uses functools.wraps, reads the X-Twilio-Signature header and full request URL, calls RequestValidator.validate, aborts with 403 for invalid signatures, and applying @require_twilio_signature to all inbound webhook routes.

Conclusion

Flask and Twilio together provide a lightweight, Blueprint-organized SMS integration that fits Flask's explicit, minimal approach without requiring a full framework. Contact Telphi Consulting to implement and configure Twilio SMS in your Flask application.

Share this article:
0 views

Ready to Transform Your Business Communications?

Get a free consultation with our VoIP experts and discover how we can help you save costs, improve efficiency, and scale your business.

Comments (0)

Join the discussion and share your thoughts (AI-moderated for quality)

Protected by AI moderation

Be the first to comment

No comments yet. Share your thoughts below.