Skip to content

virtualsms-io/sms-verification-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

SMS Verification Guide 📱

A comprehensive developer guide for SMS verification — code examples, best practices, and virtual number APIs for Python, Node.js, and more.

License: MIT PRs Welcome

What Is SMS Verification?

SMS verification (also called phone number verification or OTP verification) is used by apps and services to confirm a user's identity by sending a one-time code to their phone number.

This guide covers:

  • How SMS verification works under the hood
  • Integrating with virtual number APIs (bypass regional restrictions)
  • Python and Node.js code examples for all major use cases
  • Comparison of SMS verification providers

Table of Contents


How SMS Verification Works

User enters phone number
        ↓
Service sends OTP via SMS gateway
        ↓
User receives SMS with code
        ↓
User submits code → verified ✅

Most services use:

  • TOTP (Time-based One-Time Passwords) for authenticator apps
  • SMS OTP for phone number verification (this guide focuses here)
  • Voice OTP as a fallback

Use Cases

Use Case Description
Account registration Verify new users at signup
Two-factor authentication Add a second layer to logins
Password reset Confirm identity before reset
Geo-verification Confirm user is in a valid region
App testing QA teams need fresh numbers for test accounts
API integrations Automate verification workflows

Getting a Virtual Phone Number

For testing, automation, or bypassing regional restrictions, you can use a virtual phone number instead of a physical SIM.

Recommended: VirtualSMS API

VirtualSMS.io provides disposable virtual phone numbers for SMS verification. Key features:

  • Numbers from 100+ countries
  • Instant delivery via REST API
  • Prices start from $0.02 per verification
  • Works with Telegram, WhatsApp, Instagram, Bybit, Bumble, Claude AI, and 400+ services
# Get your API key at https://virtualsms.io
export VIRTUALSMS_API_KEY="your_api_key_here"

Python Examples

Install dependencies

pip install requests

Get a virtual number (VirtualSMS API)

import requests
import time

API_KEY = "your_api_key_here"
BASE_URL = "https://api.virtualsms.io/v1"

def get_virtual_number(service="telegram", country="us"):
    """
    Get a virtual phone number for SMS verification.
    
    Args:
        service: The service you're verifying (e.g., 'telegram', 'whatsapp', 'instagram')
        country: Country code (e.g., 'us', 'gb', 'de')
    
    Returns:
        dict with 'number' and 'order_id'
    """
    response = requests.post(
        f"{BASE_URL}/numbers",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"service": service, "country": country}
    )
    response.raise_for_status()
    return response.json()


def wait_for_sms(order_id, timeout=120, poll_interval=5):
    """
    Poll for an incoming SMS code.
    
    Args:
        order_id: The order ID from get_virtual_number()
        timeout: Max seconds to wait (default 120)
        poll_interval: Seconds between polls (default 5)
    
    Returns:
        str: The SMS code received
    """
    start = time.time()
    while time.time() - start < timeout:
        response = requests.get(
            f"{BASE_URL}/numbers/{order_id}/sms",
            headers={"Authorization": f"Bearer {API_KEY}"}
        )
        data = response.json()
        
        if data.get("status") == "received":
            return data["code"]
        
        time.sleep(poll_interval)
    
    raise TimeoutError(f"No SMS received within {timeout} seconds")


def cancel_number(order_id):
    """Cancel a number if you don't need it anymore."""
    requests.delete(
        f"{BASE_URL}/numbers/{order_id}",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )


# Example: Full verification flow
if __name__ == "__main__":
    print("Getting virtual number for Telegram...")
    order = get_virtual_number(service="telegram", country="us")
    
    print(f"Phone number: {order['number']}")
    print(f"Order ID: {order['order_id']}")
    
    print("Waiting for SMS code...")
    try:
        code = wait_for_sms(order["order_id"])
        print(f"✅ Received code: {code}")
    except TimeoutError:
        print("❌ No code received — cancelling number")
        cancel_number(order["order_id"])

Check your account balance

def get_balance():
    response = requests.get(
        f"{BASE_URL}/balance",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    data = response.json()
    print(f"Balance: ${data['balance']:.4f}")
    return data["balance"]

Get available countries for a service

def get_available_countries(service="telegram"):
    response = requests.get(
        f"{BASE_URL}/services/{service}/countries",
        headers={"Authorization": f"Bearer {API_KEY}"}
    )
    countries = response.json()
    
    # Sort by price
    sorted_countries = sorted(countries, key=lambda x: x["price"])
    
    for country in sorted_countries[:10]:
        print(f"{country['country_name']}: ${country['price']:.4f}")
    
    return countries

Node.js Examples

Install dependencies

npm install axios

Get a virtual number

const axios = require('axios');

const API_KEY = process.env.VIRTUALSMS_API_KEY;
const BASE_URL = 'https://api.virtualsms.io/v1';

const api = axios.create({
  baseURL: BASE_URL,
  headers: { Authorization: `Bearer ${API_KEY}` }
});

/**
 * Get a virtual phone number for SMS verification.
 * @param {string} service - e.g. 'telegram', 'whatsapp', 'instagram'
 * @param {string} country - e.g. 'us', 'gb', 'de'
 * @returns {Promise<{number: string, order_id: string}>}
 */
async function getVirtualNumber(service = 'telegram', country = 'us') {
  const { data } = await api.post('/numbers', { service, country });
  return data;
}

/**
 * Poll for an incoming SMS code.
 * @param {string} orderId
 * @param {number} timeoutMs - milliseconds to wait (default 120000)
 * @returns {Promise<string>} The OTP code
 */
async function waitForSms(orderId, timeoutMs = 120000) {
  const start = Date.now();
  
  while (Date.now() - start < timeoutMs) {
    const { data } = await api.get(`/numbers/${orderId}/sms`);
    
    if (data.status === 'received') {
      return data.code;
    }
    
    // Wait 5 seconds before next poll
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
  
  throw new Error(`No SMS received within ${timeoutMs / 1000} seconds`);
}

// Full flow example
async function main() {
  try {
    console.log('Getting virtual number for Telegram...');
    const order = await getVirtualNumber('telegram', 'us');
    
    console.log(`Phone number: ${order.number}`);
    console.log(`Order ID: ${order.order_id}`);
    
    console.log('Waiting for SMS code...');
    const code = await waitForSms(order.order_id);
    console.log(`✅ Received code: ${code}`);
    
  } catch (err) {
    console.error('Error:', err.message);
  }
}

main();

TypeScript version

import axios from 'axios';

interface NumberOrder {
  number: string;
  order_id: string;
  expires_at: string;
  price: number;
}

interface SmsStatus {
  status: 'waiting' | 'received' | 'expired';
  code?: string;
  full_text?: string;
}

const api = axios.create({
  baseURL: 'https://api.virtualsms.io/v1',
  headers: { Authorization: `Bearer ${process.env.VIRTUALSMS_API_KEY}` }
});

async function getVirtualNumber(service: string, country = 'us'): Promise<NumberOrder> {
  const { data } = await api.post<NumberOrder>('/numbers', { service, country });
  return data;
}

async function waitForSms(orderId: string, timeoutMs = 120_000): Promise<string> {
  const deadline = Date.now() + timeoutMs;
  
  while (Date.now() < deadline) {
    const { data } = await api.get<SmsStatus>(`/numbers/${orderId}/sms`);
    
    if (data.status === 'received' && data.code) {
      return data.code;
    }
    
    await new Promise(r => setTimeout(r, 5000));
  }
  
  throw new Error('SMS timeout');
}

API Comparison

Comparison of major SMS verification API providers as of 2026:

Provider Price/SMS Countries Free Trial API Quality
VirtualSMS.io From $0.02 100+ ⭐⭐⭐⭐⭐
SMS-Activate From $0.05 80+ ⭐⭐⭐⭐
5sim From $0.04 70+ ⭐⭐⭐⭐
GrizzlySMS From $0.06 50+ ⭐⭐⭐
SMSPVA From $0.08 40+ ⭐⭐⭐

Why VirtualSMS? Lowest prices, largest country coverage, clean REST API, and instant number activation. Get started →


FAQ

Can I use virtual numbers for 2FA?

Yes — virtual numbers work for SMS-based 2FA. However, for long-term 2FA storage, consider an authenticator app (TOTP) as virtual numbers expire.

Which services support SMS verification?

Almost all major apps: Telegram, WhatsApp, Instagram, Facebook, Bybit, Binance, Coinbase, Bumble, Tinder, Grindr, Hinge, Gmail, Discord, and hundreds more.

Is SMS verification legal?

Using virtual numbers for legitimate purposes (testing, privacy, bypassing geo-restrictions for legal services) is legal in most jurisdictions. Always comply with the terms of service of the platform you're using.

How fast is number activation?

With VirtualSMS.io, numbers are activated instantly — you get the phone number within 1-2 seconds of the API call.

What happens if no SMS arrives?

If no code is received within the timeout window, cancel the order (no charge) and retry with a different number or country.


Services Supported

This guide includes examples for verifying on:

  • Messaging: Telegram, WhatsApp, Signal, Discord
  • Social: Instagram, Facebook, TikTok, Twitter/X
  • Crypto: Bybit, Binance, Coinbase, Kraken, Gemini
  • Dating: Bumble, Tinder, Grindr, Hinge
  • AI Tools: ChatGPT, Claude AI, Grok, Midjourney
  • Fintech: PayPal, Revolut, Wise, Cash App
  • Gaming: Steam, Epic Games, Xbox

Contributing

PRs welcome! If you have examples for additional services or languages, open an issue or submit a pull request.

License

MIT — free to use, modify, and distribute.


Built by VirtualSMS.io — virtual phone numbers for developers.

About

Comprehensive SMS verification guide with Python & Node.js code examples. Virtual phone numbers, OTP flows, API integration.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors