
How to Send an SMS from Your Android Phone with Python
Use a short Python script and your Android phone to send real SMS messages: no Twilio, no carrier contracts. Just textbee, requests, and a small script.
Most SMS APIs charge you per message and route texts through shared short codes your recipients don't recognize. With textbee, the message leaves from your Android phone: your number, your SIM, your carrier rate. Python just tells it what to send.
Here's the entire flow: install the textbee app on your Android device, grab an API key, and run a script. That's it.
Prerequisites
- textbee app installed and linked to your account: download here, then follow the quickstart
- Your device ID and API key from the textbee dashboard
- Python 3 with
requestsinstalled (pip install requests) - Android 15+ users: SMS permissions need an extra step. See the permissions guide
The script
import os
import requests
DEVICE_ID = os.environ["TEXTBEE_DEVICE_ID"]
API_KEY = os.environ["TEXTBEE_API_KEY"]
def send_sms(to: str, body: str) -> dict:
resp = requests.post(
f"https://api.textbee.dev/api/v1/gateway/devices/{DEVICE_ID}/send-sms",
json={"recipients": [to], "message": body},
headers={"x-api-key": API_KEY},
timeout=30,
)
resp.raise_for_status()
return resp.json()
result = send_sms("+15551234567", "Hello from Python")
print(result)
Set TEXTBEE_DEVICE_ID and TEXTBEE_API_KEY as environment variables (don't hard-code them). A .env file with python-dotenv works too.
What the API returns
A successful call means your message was accepted and queued for the device to process (not that delivery to the handset is already finished). The body is wrapped in data, for example:
{
"data": {
"success": true,
"message": "SMS added to queue for processing",
"smsBatchId": "…",
"recipientCount": 1
}
}
After you send: open the textbee dashboard to see each message move through states like sent, delivered, or failed. If you have webhooks configured, you can get notified there too.
If something is wrong (device offline, bad API key, invalid payload), you get a non-2xx HTTP status and a JSON error body with "success": false, so keep using raise_for_status() or inspect the body on failure.
A few things to keep in mind
Phone numbers: You can use local numbers without a country code when sending within the same country (for example, a 10-digit national number). We still recommend E.164 when you can (+ then country code and number, e.g. +15551234567), especially for international or automated sends, so formatting stays unambiguous.
Multiple recipients: Pass more numbers in the recipients array. One API call, multiple messages, same SIM.
Don't spam: These are real messages from your real phone number. Make sure recipients have opted in. If you're unsure about the rules, the SMS compliance checklist is a good starting point.
Unlike traditional SMS gateways that charge per message, textbee works with your existing carrier plan. Check out the pricing to see what's included.
Where to go from here
- How to send SMS programmatically: examples in more languages
- API documentation: full endpoint reference
- Pricing and plans
You may also like
textbee.dev SMS Gateway Quickstart
Get started with textbee.dev SMS Gateway in minutes. Learn how to send and receive SMS messages using your Android phone as an SMS gateway for your applications.
Setting Up Two-Factor Authentication (2FA) with textbee SMS Gateway
A practical guide to implementing SMS-based two-factor authentication using textbee.dev. Step-by-step instructions with code examples.

textbee.dev Use Cases
Discover how businesses and developers leverage textbee.dev SMS Gateway for a wide variety of applications. Get inspired by these common use cases and implementations.