If you've ever tried to add WhatsApp messaging to a Python app, you know the pain. The official WhatsApp Business API requires a verified Facebook Business account, a Meta Business Manager setup, and a waiting period that can stretch weeks — before you've sent a single message.
This tutorial shows you a simpler way. You'll go from zero to sending a real WhatsApp message in Python in under 5 minutes, using the WA Messaging Bot API on RapidAPI.
What You'll Build
By the end of this tutorial you'll have a Python script that:
- Creates a WhatsApp session
- Authenticates via a QR code (once, then it persists)
- Sends a text message to any WhatsApp number
No Meta account. No business verification. No per-conversation fees.
Prerequisites
- Python 3.7+
- The
requestslibrary (pip install requests) - A free RapidAPI account
- A phone with WhatsApp installed
Step 1 — Get Your Free API Key
- Go to rapidapi.com and create a free account
- Search for "WhatsApp Messaging Bot" or go directly to the API listing
- Subscribe to the Basic plan (free, 100 requests/month, no credit card)
- Copy your
X-RapidAPI-Keyfrom the API Settings panel
You'll use this key in every request.
Step 2 — Create a Session
A session represents a connected WhatsApp account. Think of it like a named slot for your WhatsApp number.
import requests
API_KEY = "YOUR_RAPIDAPI_KEY"
BASE_URL = "https://whatsapp-messaging-bot.p.rapidapi.com/v1"
HEADERS = {
"x-rapidapi-key": API_KEY,
"x-rapidapi-host": "whatsapp-messaging-bot.p.rapidapi.com",
"Content-Type": "application/json"
}
# Create a session
response = requests.post(
f"{BASE_URL}/sessions",
headers=HEADERS
)
print(response.json())
# → {"success": true, "data": {"name": "my-session", "status": "STOPPED"}}
Step 3 — Start the Session and Get a QR Code
Now start the session to initiate the WhatsApp connection:
# Start the session
requests.post(
f"{BASE_URL}/sessions/start",
json={"name": "my-session"},
headers=HEADERS
)
# Get the QR code and save it as an image
qr_response = requests.get(
f"{BASE_URL}/my-session/auth/qr?format=binary",
headers=HEADERS
)
with open("qr-code.png", "wb") as f:
f.write(qr_response.content)
print("QR code saved! Open qr-code.png and scan it with WhatsApp.")
Open qr-code.png, then on your phone:
- Open WhatsApp → Settings → Linked Devices
- Tap "Link a Device"
- Scan the QR code
⚠️ QR codes expire in ~60 seconds. If it expires, just call the endpoint again for a fresh one.
Once scanned, your session status changes to WORKING. You only need to do this once — the session persists.
Step 4 — Send Your First Message
response = requests.post(
f"{BASE_URL}/sendText",
json={
"chatId": "14155552671", # Replace with the recipient's number (with country code)
"text": "Hello! 👋 This is my first WhatsApp message from Python.",
"session": "session_name"
},
headers=HEADERS
)
print(response.json())
# → {"success": true, "data": {"id": "true_14155552671@c.us_ABCDEF123456", ...}}
That's it. The message appears in WhatsApp instantly.
💡 Tip: Always include the country code in the phone number, with no spaces or dashes. For example, a US number would be
14155552671.
Bonus — Verify a Number Before Sending
Avoid delivery failures by checking if a number is on WhatsApp first:
response = requests.get(
f"{BASE_URL}/contacts/check-exists",
params={"phone": "14155552671", "session": "my-session"},
headers=HEADERS
)
data = response.json()
if data.get("numberExists"):
print("Number is on WhatsApp! Chat ID:", data["chatId"])
else:
print("Number is NOT on WhatsApp.")
Use the returned chatId (not the raw phone number) for all subsequent sends — this is especially important for Brazilian numbers.
Bonus — Send an Image
response = requests.post(
f"{BASE_URL}/sendImage",
json={
"chatId": "14155552671",
"file": {
"url": "https://example.com/photo.jpg",
"mimetype": "image/jpeg"
},
"caption": "Check this out! 🔥"
},
headers=HEADERS
)
The API also supports files, voice notes, video, location, reactions, and group/channel broadcasting. Full docs at whatsapp-messaging.retentionstack.agency.
Full Script
Here's everything in one place:
import requests
API_KEY = "YOUR_RAPIDAPI_KEY"
BASE_URL = "https://whatsapp-messaging-bot.p.rapidapi.com/v1"
SESSION = "my-session"
RECIPIENT = "14155552671" # Replace with real number
HEADERS = {
"x-rapidapi-key": API_KEY,
"x-rapidapi-host": "whatsapp-messaging-bot.p.rapidapi.com",
"Content-Type": "application/json"
}
# 1. Create session
requests.post(f"{BASE_URL}/sessions", json={"name": SESSION}, headers=HEADERS)
# 2. Start session
requests.post(f"{BASE_URL}/sessions/start", json={"name": SESSION}, headers=HEADERS)
# 3. Get QR code
qr = requests.get(f"{BASE_URL}/{SESSION}/auth/qr?format=binary", headers=HEADERS)
with open("qr-code.png", "wb") as f:
f.write(qr.content)
input("Scan qr-code.png with WhatsApp, then press Enter to continue...")
# 4. Send message
response = requests.post(
f"{BASE_URL}/sendText",
json={"chatId": RECIPIENT, "text": "Hello from Python! 👋"},
headers=HEADERS
)
print(response.json())
Pricing
The API is hosted on RapidAPI with a free tier:
| Plan | Price | Requests/month | Sessions |
|---|---|---|---|
| Basic | Free | 100 | 1 |
| Pro | $4.99/mo | 1,000 | 3 |
| Ultra ⭐ | $14.99/mo | 10,000 | 10 |
| Mega | $49/mo | 50,000 | Unlimited |
The free plan is enough to prototype and test everything in this tutorial.
What You Can Build With This
Once you have messaging working, the use cases open up fast:
- OTP / 2FA — send one-time passwords via WhatsApp instead of SMS
- Order notifications — automated shipping and delivery updates for e-commerce
- Appointment reminders — reduce no-shows with automated WhatsApp reminders
- Monitoring alerts — send server/app alerts directly to your WhatsApp
- WhatsApp bots — combine with webhooks to receive and reply to incoming messages
Wrapping Up
In 5 minutes you went from zero to sending a real WhatsApp message from Python — without a Meta account, business verification, or per-conversation fees.
Links:
If you build something with it, drop a comment below — I'd love to see what you make. And if you run into any issues, I'm happy to help debug in the comments.
Built by Retention Stack · support@retentionstack.agency
Top comments (0)