VirtualSMS Node.js SDK
v2.0.0 is a breaking rewrite. This version talks to
/api/v1/*REST endpoints directly and drops the legacy/stubs/handler_api.phpdispatcher entirely, see Migrating from v1.x below if you're upgrading.
What is VirtualSMS?
Official Node.js and TypeScript SDK for the VirtualSMS API. VirtualSMS is an account verification platform for individuals, developers, and AI agents: one-time SMS verification, dedicated number rentals, matching-country proxies, and private cloud browser sessions (beta), all behind one API, one MCP server, and one prepaid balance. This SDK gives you a typed client over the REST API, backed by real carrier-issued mobile numbers (real physical SIM cards, not VoIP) across 2500+ services in 145+ countries.
Built for developers and AI agents: REST API, hosted MCP server, SDKs.
Installation
npm install virtualsms-sdk
Requires Node.js 18+.
Quick Start
import { VirtualSMS } from 'virtualsms-sdk';
// Get your API key at https://virtualsms.io/dashboard (Settings, API Keys)
const client = new VirtualSMS(process.env.VIRTUALSMS_API_KEY!);
// 1. Buy a number for WhatsApp verification
const order = await client.createOrder('wa', 'US');
console.log(`Use this number: ${order.phone_number}`);
// 2. Poll or block until the code arrives
const result = await client.waitForSms(order.order_id);
if (result.success) {
console.log(`Verification code: ${result.code}`);
}
CommonJS works identically:
const { VirtualSMS } = require('virtualsms-sdk');
const client = new VirtualSMS('vsms_your_api_key');
Capabilities
- One-time SMS verification. Receive a code for a service like WhatsApp, Telegram, Discord, or a dating app, on demand, from $0.05 per code.
- Dedicated number rentals. Hold one number for 1-30 days and receive SMS from any service on that number, from $0.25/day.
- Matching-country proxies. Pair a number with an IP from the same country, across 223 proxy countries, from $1.10/GB.
- Private cloud browser sessions (beta). Start a country-matched browser in a live viewer for the signup step itself, invite-only.
Why real SIM cards
VirtualSMS runs on real carrier-issued mobile numbers, backed by real physical SIM cards, not VoIP. Services like WhatsApp, Telegram, Discord, and dating apps run a carrier lookup before they send a code, and VoIP or virtual numbers fail that check more often than a real SIM does. A physical SIM on a real carrier network reads like any other phone on that network, carriers like Vodafone, O2, and T-Mobile depending on the country, which is part of why VirtualSMS holds a 95%+ success rate across 2500+ services in 145+ countries.
Constructor
new VirtualSMS(apiKey: string, options?: { baseUrl?: string; timeout?: number })
| Param | Default | Notes |
|---|---|---|
apiKey |
none | Required. Get one at virtualsms.io. |
options.baseUrl |
https://virtualsms.io/api/v1 |
Override for testing/proxying. Also settable via VIRTUALSMS_BASE_URL env var. |
options.timeout |
30 (seconds) |
Per-request timeout. |
Errors
Every error thrown by the SDK is a VirtualSMSError subclass, mapped from the HTTP status the API
returned:
| Class | HTTP status | Meaning |
|---|---|---|
BadApiKeyError |
401 | Invalid or missing API key |
InsufficientBalanceError |
402 | Balance too low, top up at virtualsms.io |
NotFoundError |
404 | Order/rental/proxy id not found |
RateLimitedError |
429 | Slow down, never auto-retried |
ServerError |
5xx | .mutating is true if this was a POST/PUT/PATCH/DELETE. Do not blindly retry a mutating call, verify with a read call (listOrders/getOrder/etc.) whether it actually went through first. |
ApiError |
other 4xx | Generic fallback carrying the raw backend message |
CooldownActiveError |
none, client-side | cancelOrder/swapNumber pre-check found the 120s post-purchase cooldown still active |
import { VirtualSMS, InsufficientBalanceError } from 'virtualsms-sdk';
try {
await client.createOrder('wa', 'US');
} catch (err) {
if (err instanceof InsufficientBalanceError) {
console.log('Top up at https://virtualsms.io');
}
}
GET requests are retried up to 3 times (300ms, 600ms exponential backoff) on network failure or a 5xx response. Mutating requests are never auto-retried by the SDK.
Method reference
All 46 in-scope REST v1 surface methods are implemented. Full param/response shapes are in
src/types.ts.
Activations / Orders
client.listServices() // Service[]
client.listCountries() // Country[]
client.getPrice(service, country) // Price, real stock, fails closed
client.createOrder(service, country) // Order
client.getOrder(orderId) // Order
client.getSms(orderId) // poll once
client.waitForSms(orderId, timeoutSeconds?, intervalSeconds?) // block until arrival or timeout
client.cancelOrder(orderId) // refund before SMS
client.swapNumber(orderId) // new number, same service/country, no extra charge
client.retryOrder(orderId) // ask for a resend to the SAME number
client.listOrders(status?)
client.orderHistory({ status?, service?, country?, since_days?, limit? })
client.cancelAllOrders() // bulk-cancel every active order
client.searchServices(query) // fuzzy match "uber" to service code
client.findCheapest(service, limit?) // cheapest in-stock countries
Rentals
Two tiers, same refund terms (full refund within 20 minutes of purchase, before the first SMS):
full_access: local SIM inventory, usable for any service.platform: sourced via our global supplier network, one service per number, 24/72/168h durations only.
client.rentalsPricing()
client.rentalsAvailable({ country?, service?, type?, tier? })
client.rentalsServices(countryCode, durationHours?)
client.rentalsPrice(service, countryCode, durationHours)
client.createRental({ tier, country, duration_hours, service?, auto_renew? })
client.listRentals(status?)
client.getRental(rentalId)
client.extendRental(rentalId, durationHours)
client.cancelRental(rentalId)
Proxies
client.listProxyCatalog()
client.listProxies()
client.buyProxy({ pool_type, gb, country_code? })
client.rotateProxy(proxyId, port?)
client.getProxyUsage(proxyId)
client.getProxyUsageHistory(proxyId, range?)
client.setProxyTargeting(proxyId, { country_code, cities?, asns? })
client.testProxy(proxyId, { country, session?, protocol? })
client.listProxyLocations(poolType, country, kind)
client.generateProxyEndpoint({ proxy_id, country_code, target_by?, location_code?, session?, ... })
Account
client.getBalance()
client.getProfile()
client.getTransactions({ type?, from?, to?, limit?, offset? })
client.getStats(sinceDays?)
Session (beta)
client.startManualRegistrationSession({ service_name?, country?, device_mode?, ... })
Invite-only beta. Throws a clean "join https://t.me/VirtualSMS_io" error if your account isn't allowlisted yet.
Other
client.checkNumber(e164Number) // carrier + line-type lookup, no auth required
Webhooks
client.listWebhooks()
client.createWebhook({ url, description?, events, threshold? }) // secret returned ONCE, store it immediately
client.getWebhook(id)
client.updateWebhook(id, { url?, description?, events?, threshold?, active?, paused? })
client.deleteWebhook(id)
client.testWebhook(id)
client.listWebhookDeliveries(id, { limit?, offset? })
Examples
See examples/:
activation.ts: buy a number, wait for the coderental.ts: check availability, rent, extend, cancelproxy.ts: catalog, buy, generate connection string, rotate
Migrating from v1.x
v1.x wrapped the legacy sms-activate-compatible /stubs/handler_api.php dispatcher. v2.0.0 is a
breaking rewrite: it talks to /api/v1/* REST endpoints directly and the legacy dispatcher is
not used at all. Method names, constructor shape, and response shapes all changed, this is not a
drop-in upgrade. If you're still on v1.x and need the old surface, pin "virtualsms-sdk": "^1.0.0".
AI agents and MCP
This SDK is the API-client half: a typed wrapper an application or agent framework calls directly. The hosted MCP server is the separate agent-facing half, exposing the same capabilities as MCP tools for MCP-compatible clients like Claude and Cursor. Use this SDK when you're writing code that calls VirtualSMS; use the MCP server when an AI agent needs to call VirtualSMS itself without a code layer in between.
FAQ
What is VirtualSMS?
VirtualSMS is an account verification platform for individuals, developers, and AI agents. It combines one-time SMS verification, dedicated number rentals, matching-country proxies, and private cloud browser sessions behind one API, one MCP server, and one prepaid balance.
Does VirtualSMS use real SIM cards or VoIP numbers?
VirtualSMS uses real carrier-issued mobile numbers, backed by real physical SIM cards, not VoIP. Many services, including WhatsApp, Telegram, Discord, and dating apps, reject VoIP and virtual numbers at signup; a real physical SIM on a real carrier network passes that check far more often, which is reflected in a 95%+ success rate.
Which services and countries does VirtualSMS support?
VirtualSMS covers 2500+ services across 145+ countries for SMS verification and number rentals, plus matching-country proxies across 223 proxy countries. Coverage spans messaging apps, social platforms, marketplaces, dating apps, and financial services.
Can I rent a number, or only buy one-time codes?
Both. Buy a single one-time code from $0.05, or rent a dedicated number for 1-30 days from $0.25/day to receive SMS from any service on that number for the rental window.
Does VirtualSMS work with AI agents and MCP?
Yes. VirtualSMS exposes a hosted MCP server plus a REST API and official SDKs in nine languages, so an AI agent can request a number, wait for a code, or manage a rental the same way a developer would call the API directly.
How much does VirtualSMS cost?
Pricing is pay-as-you-go from one prepaid balance: SMS verification from $0.05 per code, number rentals from $0.25/day, and proxies from $1.10/GB. There is no subscription requirement.
Is there a free API key?
Yes. Creating a VirtualSMS account issues an API key immediately, at no cost. You only spend from your prepaid balance when you place an order: an activation, a rental, or a proxy.
Links
- Homepage: virtualsms.io
- Docs: virtualsms.io/docs
- MCP server: virtualsms.io/mcp
- Dashboard / API keys: virtualsms.io/dashboard
- Other SDKs: PHP · Python · Ruby · .NET · Go · Rust · Swift · Java
- GitHub: github.com/virtualsms-io
License
MIT