Blog

How to send SMS with Python

Amy Elliott Amy Elliott
· 7 min read · Tips and resources · January 13th, 2026
In this tutorial, you’ll learn how to pair your Python knowledge with a reliable SMS service and SMS API to start sending SMS with Python in minutes.

Business SMS has an incredibly high open rate of 98%. This means that SMS integration for your Python app will ensure you reach even more customers with timely alerts, such as password resets, two-factor authentication (2FA), security alerts, and appointment reminders.

And it's easier to implement than you might think. Here’s how you can get started sending SMS with Python in a few simple steps.

Prerequisites

Before you begin sending SMSes with MailerSend, make sure you have the following in place:

  • Python 3.7^: Ensure that you have Python 3.7 and above with the pip module installed on your local machine. You can download Python from the official website

  • MailerSend account: To send SMS using MailerSend, you'll need to create an account on the MailerSend platform and upgrade to one of the paid plans, all of which include a number of SMSes. Check out the pricing and sign up here

  • MailerSend phone number: If you don't have one you can learn how to get one here. Paid accounts are assigned a trial phone number that can be used to test out SMS-sending capabilities.

Getting Started

MailerSend offers a simple SMS API and advanced features to make sending text message notifications easy. Once you’ve created an account and purchased a phone number (or if you’re using the trial phone number for testing), you’ll need to retrieve your API keys by going to Integrations and clicking Manage on the API token section. Then click Create new token. You can learn more about creating API tokens in our guide. 

Remember:

Keep API keys secure and never expose them in public repositories.

How to send an SMS

To use MailerSend to send an SMS using Python, first install the MailerSend Python library. You can do this by running the following command in your console:

pip install mailersend

The MailerSend Python SDK will be installed on your local system after the command has been executed. Check out the MailerSend SDK on GitHub.

Next, set your API key as an environment variable:

export MAILERSEND_API_KEY="your_api_key_here"

Then, in your project directory, create a file called `send_sms.py` and paste the following code into it:

from mailersend import MailerSendClient, SmsSendingBuilder

ms = MailerSendClient()

try:
    request = (
        SmsSendingBuilder()
        .from_number("+1234567890")
        .to(["+1098765432"])
        .text("Hello from MailerSend SMS!")
        .build()
    )

    response = ms.sms_sending.send(request)

    print("✅ SMS sent successfully")

    if response:
        print("📨 Response:", response)

except Exception as e:
    print("❌ Failed to send SMS")
    print(f"   Error: {e}")

The MailerSend API client is created and “SmsSendingBuilder” is imported. Following that, define the .from_number as your MailerSend toll-free number. The number must be in E164 format. 

Then specify the recipient's phone number and the text you want to send. The method .to is an array that can store up to 50 numbers, so that you can send the same message in bulk. Finally, the .build method is invoked to finalize and validate the request.

Run the Python script in the console by executing the below command:

python send_sms.py

If you’ve entered everything correctly, the above command will send the SMS message to the number that you entered, returning the success message.

Sending bulk personalized SMS

The .to method, where we define the recipient number, is an array, and you can add up to 50 numbers here. This means you can send a single text message in bulk, as well as personalized messages using variables. To do this, we just add the variables to the message content and set their values with the .personalization method in the request:

from mailersend import MailerSendClient, SmsSendingBuilder

ms = MailerSendClient()

try:
    # SMS with personalization
    request = (
        SmsSendingBuilder()
        .from_number("+1234567890")
        .to(["+1098765432", "+1246809753"])
        .text("Hello {{name}}, your order {{order_id}} is ready!")
        .personalization([
            {
                "phone_number": "+1098765432",
                "data": {"name": "John", "order_id": "12345"}
            },
            {
                "phone_number": "+1246809753", 
                "data": {"name": "Jane", "order_id": "12346"}
            }
        ])
        .build()
    )

    response = ms.sms_sending.send(request)

    print("✅ SMS sent successfully")

    # Print response
    if response:
        print("📨 Response:")
        if isinstance(response, dict):
            for key, value in response.items():
                print(f"   {key}: {value}")
        else:
            print(f"   {response}")

except Exception as e:
    print("❌ Failed to send SMS")
    print(f"   Error: {e}")

You could also use personalization variables to send different message content to multiple recipients:

from mailersend import MailerSendClient, SmsSendingBuilder

ms = MailerSendClient()

try:
    # SMS with personalization
    request = (
        SmsSendingBuilder()
        .from_number("+1234567890")
        .to(["+1098765432", "+1246809753"])
        .text("Hello {{name}}, {{custom_message}}")
        .personalization([
            {
                "phone_number": "+1098765432",
                "data": {"name": "John", "custom_message": "your order is ready and will be with your soon!"}
            },
            {
                "phone_number": "+1246809753", 
                "data": {"name": "Jane", "custom_message": "we've detected account activity from a new device. Please login to your account to review."}
            }
        ])
        .build()
    )

    response = ms.sms_sending.send(request)

    print("✅ SMS sent successfully")

    # Print response
    if response:
        print("📨 Response:")
        if isinstance(response, dict):
            for key, value in response.items():
                print(f"   {key}: {value}")
        else:
            print(f"   {response}")

except Exception as e:
    print("❌ Failed to send SMS")
    print(f"   Error: {e}")

Sending One-time password (OTP) text messages

There are countless scenarios in which sending SMS would be useful when working with a web application. One popular use for transactional SMS is for sending one-time passwords (OTPs) to authenticate users in your Python application. 

To send an OTP, we’ll also need to generate a random number for the password. To do this, we import the built-in random module and use the randint function to return a random integer between two specified values. This is then added to the message content using the {{otp}} variable. Here’s the code:

from mailersend import MailerSendClient, SmsSendingBuilder
import random  # For OTP generation

ms = MailerSendClient()

try:
    # Generate a 6-digit OTP
    otp = random.randint(100000, 999999)

    # Build the SMS request with OTP included
    request = (
        SmsSendingBuilder()
        .from_number("+1234567890")
        .to(["+1098765432"])
        .text(f"Your verification code is: {{otp}}")
        .build()
    )

    # Send the SMS
    response = ms.sms_sending.send(request)

    # Print success message
    print("✅ SMS sent successfully")
    if response:
        print("📨 Response:", response)

except Exception as e:
    print("❌ Failed to send SMS")
    print(f"   Error: {e}")

More use case examples for sending transactional SMS

Transactional SMS does more than just improve communication. It can enhance your app’s functionality, improve the user experience, optimize the customer journey, streamline internal processes, and help strengthen security. Here are some more ways you could use an SMS API.

E-commerce SMS

  • Order confirmations

  • Link to receipt

  • Shipping confirmation/tracking details

  • Delivery status updates

  • Delivery delay alerts

  • Phone number verifications

  • OTPs and 2FA messages

  • Password reset messages

  • Refund confirmations

  • Support requests and confirmations

  • Feedback requests

SaaS SMS

  • Password reset messages

  • OTPs and 2FA (Two-factor authentication)

  • Security/fraud alerts

  • Subscription/payment confirmations

  • Phone number verifications

  • Login alerts

  • Failed payment alerts

  • Billing reminders

  • Usage alerts/warnings

  • Feedback requests

Hospitality/services SMS

  • Booking/reservation confirmations

  • Booking/reservation reminders

  • Cancellation/modification confirmations

  • Password resets/OTPs/2FA messages for online booking systems

  • Waitlist notifications

  • Payment confirmations

  • Refund confirmations

  • Check-in/check-out reminder

  • Loyalty program alerts

  • Holidays/availability notifications

  • Feedback requests

Agency SMS

  • OTPs and 2FA messages for client portal logins

  • Upcoming payment reminders

  • Failed payment alerts

  • Invoice available for download

  • Refund confirmations

  • Holidays/availability notifications

  • Meeting confirmations and reminders

  • Spend threshold alerts

  • Feedback requests

Debugging and troubleshooting SMS sending

Verify your number in MailerSend

When you purchase a new phone number, you’ll need to verify it. This involves providing some details about your company and how you plan to use SMS. This is purely to protect our users and prevent abuse of the system. Without verifying your phone number, you won’t be able to send any SMS.

Use the E164 format and validate numbers

You must use the E164 format when inputting recipient and sender phone numbers. This has a maximum of 15 digits. The numbers begin with a plus sign (+), then the mobile number and the country code (for example,+1 for the United States).

You can validate recipient phone numbers with the phonenumbers library. Here is a simple script you can use to get starter:

import phonenumbers
from phonenumbers.phonenumberutil import NumberParseException

def validate_phone_number(number: str) -> bool:
    """
    Validates if a phone number is valid and in E.164 format.
    
    Returns True if valid, False otherwise.
    """
    try:
        parsed_number = phonenumbers.parse(number, None)  # None means use international format
        return phonenumbers.is_valid_number(parsed_number)
    except NumberParseException:
        return False

# Example usage
phone_numbers = ["+18558763048", "+123456", "1234567890"]

for num in phone_numbers:
    if validate_phone_number(num):
        print(f"✅ {num} is valid")
    else:
        print(f"❌ {num} is invalid")

Check error codes and responses

If your code is up to scratch but messages are failing, your first port of call is to check the carrier response code. In MailerSend, you can go to SMS Activity to view the status, error code and message. 

If you want to learn more about error codes and messages, check out our SMS API resource.

An example of SMS activity showing the carrier error message in MailerSend.

Ensure API keys are configured correctly

If your API requests are failing, verify that you are using the correct API key, and that it has the correct permissions for sending SMS. When you create an API token for SMS sending in MailerSend, make sure you give the token Full access or Custom access with the Full access option selected for SMS.

Use webhooks for improved monitoring

Webhook events for sent, delivered and failed statuses allow you to receive real-time notifications when they occur, making it easier to identify and fix issues before they impact your customers or workflows.

Transactional SMS compliance best practices

Compliance with local rules and industry standards is critical while sending SMS messages. There are government rules and procedures in place that detail how to send SMS messages. Failure to follow these regulations may result in legal consequences and harm to your reputation. Here are some best practices and tips:

Obtain the appropriate consent 

Before sending an SMS, ensure you have explicit consent from recipients. You must also provide a means for recipients to opt out of receiving your text messages to comply with MailerSend's terms of service and the Cellular Telecommunications Industry Association's (CTIA) requirements.

Use a valid sender number

Make sure you send your text messages from a working phone number to guarantee error-free delivery and the greatest experience for the receivers. The number needs to be active on your account.

Keep it SHAFT-free 

SHAFT is a CTIA-created regulation that forbids businesses from transmitting any material that advocates or contains sexual content, hate speech, alcohol, firearms, or tobacco. There are certain exceptions: businesses selling tobacco or alcohol must employ age-gating to safeguard underage customers and keep them from consenting to SMS marketing.

Check out our guide on SMS compliance to learn more about different types of SMS, the consent needed for each one, and more in-depth best practices.

Sending SMS with Python is simple

You now know how to easily combine Python with MailerSend for SMS. It’s actually pretty straightforward—you can instantly send your recipients an SMS message with only a few lines of Python code. And, although you might be eager to start sending right away, we highly recommend you familiarize yourself with SMS compliance best practices first to ensure the best user experience.

Have you sent text messages with Python? We'd love to hear your tips, tricks, and recommendations in the comments.

Amy Elliott
I’m Amy, Content Writer at MailerSend. As a child, I dreamt about writing a book and practiced by tearing pages from an A4 notepad and binding them with sugar paper. The book is pending but in the meantime, I love taking a deep dive into technical topics and sharing insights on email metrics and deliverability.