Skip to main content
US Non-VoIP Numbers99% SMS Code Reception Success RateVerified in 5โ€“30 seconds
RCVSMS
โ† Back to blog
APIยท 18 min read

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.

Omar Hassan

What you'll build

By the end of this tutorial, you'll have a working Python script that:

  1. Authenticates with the RCVSMS API
  2. Rents a phone number for SMS verification
  3. Polls for incoming SMS
  4. Verifies HMAC-signed webhooks
  5. 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