SMS Verification Guide ๐ฑ
March 22, 2026 ยท View on GitHub
A comprehensive developer guide for SMS verification โ code examples, best practices, and virtual number APIs for Python, Node.js, and more.
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
- Use Cases
- Getting a Virtual Phone Number
- Python Examples
- Node.js Examples
- API Comparison
- FAQ
- Contributing
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.