WhatsApp API + Python: Send Your First Message in 5 Minutes

Published: May 17, 2026
- The honest answer: most Python developers shouldn't build this from scratch
- Option 1 · Meta Cloud API (free, direct)
- Receiving messages with a Flask webhook
- Option 2 · Twilio WhatsApp (fastest sandbox)
- Webhook handler with Twilio signature verification
- Option 3 · Instant Reply REST API (managed inbox)
- Webhook signature verification
- The real comparison: dev time + dev cost + 12 months from now
- Common gotchas that will burn an afternoon
- 1 · The 24-hour window
- 2 · Phone number format
- 3 · Don't compare signatures with ==
- 4 · Avoid these libraries
- Production checklist
- The 10-minute path: skip the build, ship the result
People Also Ask
Related Questions
The honest answer: most Python developers shouldn't build this from scratch
You want Python to send a WhatsApp message. Maybe a price drop alert. Maybe an order shipped notification. Maybe a real chatbot that closes leads.
Here's the part nobody tells you upfront: the API call itself takes 10 lines of Python. Everything else takes 3 to 6 months. The webhook handler. The signature verification. The 24-hour customer-care window logic. The retry queue. The team inbox UI. The AI replies. The voice note transcription. The image understanding. The CRM sync. The analytics. The number ban risk if you make one mistake.
You have three real choices:
- Instant Reply (recommended for 9 out of 10 readers): a managed AI inbox running on the WhatsApp Business Platform with a Python-friendly REST API. Send + receive + AI replies + voice transcription + image understanding + team inbox + CRM sync, free on every plan. 10-day Pro trial means you ship today.
- Meta Cloud API: the raw endpoint. Free per request, but you spend the next quarter building the inbox around it.
- Twilio: a Meta BSP wrapper. Fastest sandbox to test in. Still no inbox UI, still no AI, and per-message fees scale with you.
The rest of this post gives you working Python code for all three so you can decide for yourself. Spoiler: if you are building a real business and not a personal weekend hack, Instant Reply will save you six months and twenty thousand dollars. The numbers are at the bottom.
Option 1 · Meta Cloud API (free, direct)
The Meta Cloud API is the cheapest and most direct path. You need:
- A WhatsApp Business Account (WABA) verified in Meta Business Manager. Takes 5 to 60 minutes depending on Meta's review.
- A phone number ID from the Cloud API setup screen.
- A permanent access token (System User token) so your script does not need to refresh OAuth tokens.
Once you have those, sending a message is one POST request:
import os
import requests
PHONE_ID = os.environ["WA_PHONE_NUMBER_ID"]
TOKEN = os.environ["WA_PERMANENT_TOKEN"]
URL = f"https://graph.facebook.com/v18.0/{PHONE_ID}/messages"
def send_text(to_e164: str, body: str):
r = requests.post(
URL,
headers={"Authorization": f"Bearer {TOKEN}"},
json={
"messaging_product": "whatsapp",
"to": to_e164,
"type": "text",
"text": {"body": body},
},
timeout=10,
)
r.raise_for_status()
return r.json()
if __name__ == "__main__":
print(send_text("+14155551234", "Your order is on its way."))
That is it. The response includes a message ID you can store for delivery tracking. Phone numbers must be in E.164 format (country code, no plus). Errors come back as JSON with a Meta error code; the most common ones are 131000 (general error) and 131005 (rate limit). Wrap in a retry loop for production.
Receiving messages with a Flask webhook
For two-way conversations, expose a webhook. Meta posts JSON to your URL whenever a customer messages you, replies, or reads a message. Verify the signature on every request:
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
APP_SECRET = os.environ["WA_APP_SECRET"].encode()
VERIFY_TOKEN = os.environ["WA_VERIFY_TOKEN"]
def verify_signature(raw_body: bytes, sig_header: str) -> bool:
expected = "sha256=" + hmac.new(APP_SECRET, raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig_header or "")
@app.route("/webhook", methods=["GET", "POST"])
def webhook():
if request.method == "GET":
# Verification handshake
if request.args.get("hub.verify_token") == VERIFY_TOKEN:
return request.args.get("hub.challenge")
abort(403)
raw = request.get_data()
if not verify_signature(raw, request.headers.get("X-Hub-Signature-256")):
abort(403)
event = request.json
# event["entry"][0]["changes"][0]["value"]["messages"][0]
# Handle incoming text, image, button reply, etc.
return ("", 200)
That's a production-ready signature check using hmac.compare_digest, which is timing-safe. Never compare signatures with ==; an attacker can probe character by character.
Option 2 · Twilio WhatsApp (fastest sandbox)
Twilio gives you a sandbox WhatsApp number you can hit in 5 minutes without a verified WABA. Useful for prototyping. Production needs a verified number, same Meta requirements.
import os
from twilio.rest import Client
client = Client(
os.environ["TWILIO_ACCOUNT_SID"],
os.environ["TWILIO_AUTH_TOKEN"],
)
message = client.messages.create(
from_="whatsapp:+14155238886", # Twilio sandbox number
to="whatsapp:+14155551234",
body="Your order is on its way.",
)
print(message.sid)
Twilio charges a per-message platform fee on top of Meta's per-conversation rate. Roughly $0.005 to $0.18 depending on country and message category. For a hobby project sending under 100 messages per month, you'll spend under $5. For 5,000 messages, expect $50 to $300 depending on your geography mix.
Webhook handler with Twilio signature verification
from twilio.request_validator import RequestValidator
import os
validator = RequestValidator(os.environ["TWILIO_AUTH_TOKEN"])
@app.route("/twilio/webhook", methods=["POST"])
def twilio_webhook():
sig = request.headers.get("X-Twilio-Signature", "")
url = request.url
params = request.form.to_dict()
if not validator.validate(url, params, sig):
abort(403)
incoming_body = request.form.get("Body")
from_number = request.form.get("From") # whatsapp:+14155551234
# Process the message...
return ("", 200)
Option 3 · Instant Reply REST API (managed inbox)
If you also want a shared inbox UI for your team, AI auto-replies, voice note transcription, image understanding, calendar booking inside the chat, and a CRM sync, the Meta Cloud API alone won't get you there. You'll spend 3 to 6 months building all that on top of it.
The Instant Reply API ships those features as a managed product. Same Python ergonomics, broader surface area: send across WhatsApp, Instagram DMs, and Messenger from a single endpoint.
import os, requests
IR_API_KEY = os.environ["IR_API_KEY"]
BASE = "https://instantreply.up.railway.app/v1"
def send_message(conversation_id: str, content: str):
r = requests.post(
f"{BASE}/conversations/{conversation_id}/messages",
headers={
"Authorization": f"Bearer {IR_API_KEY}",
"Content-Type": "application/json",
},
json={"content": content, "content_type": "text"},
timeout=10,
)
r.raise_for_status()
return r.json()
# List all open conversations across WhatsApp, IG, Messenger:
def list_open():
r = requests.get(
f"{BASE}/conversations?status=active&limit=100",
headers={"Authorization": f"Bearer {IR_API_KEY}"},
timeout=10,
)
r.raise_for_status()
return r.json()["data"]
if __name__ == "__main__":
for conv in list_open():
if "refund" in (conv.get("last_message_preview") or "").lower():
send_message(conv["id"], "Hi! Your refund is processed. Confirmation email in 2 minutes.")
Test keys start with ir_test_ and run in a sandboxed mode: no real messages ever go out. Live keys start with ir_live_. Switch between them by changing one environment variable.
Webhook signature verification
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
SIGNING_SECRET = os.environ["IR_WEBHOOK_SECRET"].encode() # starts with whsec_
@app.route("/instantreply/webhook", methods=["POST"])
def ir_webhook():
raw = request.get_data()
sig = request.headers.get("X-IR-Signature", "")
expected = "sha256=" + hmac.new(SIGNING_SECRET, raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig):
abort(403)
event = request.json
# event["event"] = "message.received" | "conversation.closed" | ...
# event["data"] = the payload
return ("", 200)
Failed deliveries retry on exponential backoff for 30 days. You get an at-least-once delivery guarantee, so always idempotently process the event["id"] on your side.
The real comparison: dev time + dev cost + 12 months from now
Code samples lie. They make Meta Cloud API and Twilio look like 10-line solutions. The truth comes out at month 3 when you realize you still need: webhook signature verification at scale, a 24-hour-window timer per conversation, retry queues, a team inbox UI, AI replies, voice transcription, image understanding, CRM sync, analytics, audit logs, and team seats. Here's what each path actually costs once you ship to production:
| What you need | Instant Reply | Meta Cloud API | Twilio |
|---|---|---|---|
| Time to first real message | 10 minutes | 1 to 2 weeks | 1 to 3 days |
| Team inbox UI | Included | Build it (6 to 12 weeks) | Build it (6 to 12 weeks) |
| AI auto-replies in your tone | Included, trained on your docs | Build it (4 to 8 weeks + LLM costs) | Build it (4 to 8 weeks + LLM costs) |
| Voice note transcription | Included | Build it (Whisper or paid API) | Build it (Whisper or paid API) |
| Image understanding | Included | Build it (vision API + glue) | Build it (vision API + glue) |
| Instagram + Messenger same API | Yes, single endpoint | Separate API per channel | Separate per channel |
| CRM sync (HubSpot, Pipedrive, Notion) | Native, click to connect | Build it | Build it (Studio + code) |
| Calendar booking inside the DM | Included | Build it | Build it |
| MCP server for Claude, Cursor, Windsurf | Included, free on every plan | Not offered | Not offered |
| Per-message API fee (inbox side) | None | None (Meta charges per conversation) | Platform fee + Meta fees |
| Free tier for testing | 10-day Pro trial + free plan, no card | Free API, you pay Meta | Sandbox + pay-as-you-go |
| Cost at month 12 (mid-size business) | $129/mo flat Growth plan | $50k+ in dev time + Meta fees | $500 to $900/mo + dev time |
The Python developer math is brutal: a senior engineer at $150k base costs your company roughly $90 per hour fully loaded. Six months building the inbox layer on top of Meta Cloud API is 1,000 hours, which is $90,000 of opportunity cost. Instant Reply Growth is $129 per month, or $1,548 per year. The ratio is not close. Use the open SDK to ship the actual differentiator your customers care about, not the messaging infrastructure that already exists.
Honest exception: if you are an enterprise building a proprietary messaging product where the inbox itself is the value (think Salesforce, Klaviyo), you build on Twilio. For everyone else, you use Instant Reply.
Common gotchas that will burn an afternoon
1 · The 24-hour window
Once a customer messages you, you have 24 hours to reply with any message. After 24 hours, you can only send pre-approved template messages (Meta calls these "marketing", "utility", or "authentication" templates). Free-form text outside the window is blocked. Plan around it. The Instant Reply inbox shows the window timer per conversation.
2 · Phone number format
WhatsApp wants E.164: +14155551234 (with the plus). Meta wants it without the plus: 14155551234. Twilio wants whatsapp:+14155551234. Three slightly different formats. Write a normalizer once and use it everywhere.
3 · Don't compare signatures with ==
The wrong code: if sig == expected:. The right code: hmac.compare_digest(sig, expected). The first one leaks timing info that lets an attacker probe the signature one character at a time. Always use compare_digest.
4 · Avoid these libraries
- yowsup: reverse-engineered WhatsApp Web protocol. Numbers banned.
- selenium-whatsapp: browser automation. Numbers banned.
- pywhatkit: relies on WhatsApp Web. Brittle, bannable.
- whatsapp-web.js: Node, not Python; same risk.
None of these touch the official API. Meta detects and bans the underlying numbers. Use the Cloud API, Twilio, or Instant Reply.
Production checklist
- Permanent access tokens stored in your secrets manager, not
.envin git - Signature verification on every webhook (timing-safe compare)
- Retry with exponential backoff on 5xx and rate-limit responses
- Idempotency keys on POST requests (the message ID + recipient is a good idempotency key)
- Log
X-Request-Idfrom every API response for support escalation - Monitor delivery webhooks (
sent,delivered,read,failed) - Respect the 24-hour customer-care window
The 10-minute path: skip the build, ship the result
If your goal is "send WhatsApp messages from Python", the Cloud API works. Go build it. The docs are at developers.facebook.com.
If your goal is "actually run a business that closes leads on WhatsApp, Instagram, and Messenger", you are not building a messaging library. You are building everything around it. That is six months of work you can skip.
Instant Reply gives you:
- A Python-friendly REST API for every channel (live OpenAPI explorer)
- An AI closer trained on your docs and last 50 sales transcripts
- Voice note transcription and image understanding on every message
- Calendar booking inside the DM with no Calendly link
- CRM sync to HubSpot, Pipedrive, Notion, Airtable, and Zoho out of the box
- An MCP server so Claude, Cursor, Windsurf, and Zed can read your inbox too
- The whole thing live in your team's hands in 10 minutes via embedded Meta signup
10-day Pro trial, no credit card. Starts at $59/mo Starter ($49 annual) once the trial ends. Cancel any time.
Start your free 10-day Pro trial or read the 5-minute Python quickstart. Your first WhatsApp reply goes out today.
Frequently asked questions
Quick answers to what people ask most.
- Yes. Three credible paths: the Meta Cloud API (official, free, you handle WABA setup), Twilio (fastest to bootstrap, pay-per-message), and managed inbox APIs like Instant Reply (REST API across WhatsApp, Instagram, Messenger with a Python SDK). All three use plain HTTP requests, so the standard requests library handles them, and full-featured SDKs cover async + retries.
- The Meta Cloud API itself is free, but you pay Meta's per-conversation rates (roughly $0.005 for service messages and $0.0089 to $0.18 for marketing depending on country). Twilio adds a small platform fee on top. Instant Reply includes free API access on every plan (free tier 30 req/min, paid plans up to 2,400 req/min) without a per-message API fee on the inbox side.
- Start with the requests library and a single send_message function. Add a Flask or FastAPI endpoint to receive webhooks. Use the official Meta Cloud API for direct messaging or Instant Reply's REST API for a managed inbox across multiple channels. Both have working Python examples in this post.
- Meta sends a hub.verify_token query parameter on the initial webhook setup, and signs each subsequent payload with X-Hub-Signature-256 (HMAC-SHA256). Verify with hmac.compare_digest. Twilio uses X-Twilio-Signature with HMAC-SHA1 and the request body. Instant Reply uses X-IR-Signature with HMAC-SHA256 and the raw request body.
- No. WhatsApp blocks unofficial libraries (like yowsup or Selenium-based scrapers) and bans the phone numbers using them. Stick to the official Meta Cloud API, an approved BSP like Twilio, or a managed inbox like Instant Reply. The official path takes about 10 minutes via embedded signup.
- The Cloud API is Meta's direct offering: you register a WhatsApp Business Account, get free API access, and pay Meta per conversation. Twilio is a BSP (Business Solution Provider) that wraps the Cloud API and adds a unified developer experience, sub-second routing, and a small per-message platform fee. Pick Cloud API for lowest cost, Twilio for fastest setup.
- Skip yowsup, selenium-whatsapp, and pywhatkit; all rely on the unofficial WhatsApp Web protocol and risk a number ban. Use requests with the Cloud API directly, twilio-python for Twilio, or instantreply-python for the managed inbox API. All three are officially supported as of 2026.
10-day Pro trial · no credit card
Your DMs are leaking money right now.
Instant Reply answers every WhatsApp, Instagram, and Messenger DM in seconds · automatically. Most teams see their first booked appointment from an AI reply within 24 hours of connecting.
Keep reading

AI Inbox
How to Automate Instagram DM Replies Without Sounding Like a Robot
11 min read

AI Inbox
Shared Inbox vs Separate Apps: Why Unified Messaging Wins (2026)
10 min read

AI Inbox
AI Chatbot vs AI Inbox: The Real Difference (and Which You Need)
11 min read

AI Inbox
Best Shared Inbox Software in 2026 (Honest Comparison)
9 min read

AI Inbox
Omnichannel Messaging Platform: What It Is and Why It Matters
8 min read

AI Inbox
AI Customer Service: The 2026 Guide for Growing Businesses
10 min read
Explore Instant Reply
More tools and solutions
Industry solutions