SMS Verification API with Python: Complete Tutorial (2026)
Build a complete SMS verification workflow using RCVSMS Python SDK. From API key generation to webhook handling. Includes copy-paste code.
What you'll build
By the end of this tutorial, you'll have a working Python script that:
- Authenticates with the RCVSMS API
- Rents a phone number for SMS verification
- Polls for incoming SMS
- Verifies HMAC-signed webhooks
- Handles errors gracefully
Prerequisites
- Python 3.8+
pip install requests- RCVSMS account with API key
Step 1: Get your API key
Visit RCVSMS dashboard and generate an API key. Keep this secret โ anyone with the key can rent numbers on your account.
Step 2: Basic request
import requests
API_KEY = "your_api_key_here"
BASE_URL = "https://api.rcvsms.com/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# List available services
response = requests.get(f"{BASE_URL}/services", headers=headers)
services = response.json()
print(f"Found {len(services)} services")
Step 3: Rent a number
# Rent a US number for Telegram verification
payload = {
"service": "telegram",
"country": "US",
"webhook_url": "https://your-app.com/webhooks/sms"
}
response = requests.post(
f"{BASE_URL}/orders",
headers=headers,
json=payload
)
order = response.json()
print(f"Order ID: {order['id']}")
print(f"Phone number: {order['phone_number']}")
Step 4: Wait for SMS
import time
while True:
response = requests.get(
f"{BASE_URL}/orders/{order['id']}",
headers=headers
)
order = response.json()
if order['status'] == 'received':
sms_code = order['sms_code']
print(f"Received: {sms_code}")
break
elif order['status'] == 'expired':
print("No SMS received within timeout")
break
time.sleep(5) # Poll every 5 seconds
Step 5: Webhook handler (Flask)
from flask import Flask, request
import hmac
import hashlib
app = Flask(__name__)
WEBHOOK_SECRET = "your_webhook_secret"
@app.route("/webhooks/sms", methods=["POST"])
def sms_webhook():
payload = request.data
signature = request.headers.get("X-RCVSMS-Signature")
# Verify HMAC signature
expected = hmac.new(
WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
return "Invalid signature", 401
event = request.json
print(f"Order {event['order_id']} received SMS: {event['sms_code']}")
return "OK", 200
Error handling
from requests.exceptions import RequestException
def safe_request(method, endpoint, **kwargs):
try:
response = requests.request(method, f"{BASE_URL}{endpoint}", headers=headers, timeout=30, **kwargs)
response.raise_for_status()
return response.json()
except RequestException as e:
print(f"API error: {e}")
if e.response is not None:
print(f"Status: {e.response.status_code}")
print(f"Body: {e.response.text}")
raise
Rate limits
- Free tier: 60 requests/minute
- Pro tier: 600 requests/minute
- Enterprise: Custom
Next steps
- Add retry logic with exponential backoff
- Use connection pooling for high-volume usage
- Cache service/country lists to reduce API calls
- Implement webhook idempotency to avoid duplicates
Full Python SDK available at github.com/rcvsms/python-sdk.
Ready to rent your first number?
Get started in under 2 minutes. No subscription required.
Get started for $0.24