SMS verification API
Last modified at 2026/11/03
Running queries to the API
Two APIs share one key: a REST API with JSON, and the SMS activation format that many tools already use. Create the key on the API key page of the console; it is shown once. Limit: 300 requests per minute per key. Each order has a 20 minute code window, the same as in the console.
# REST API (JSON) curl https://virtualsns.com/api/v1/balance -H "Authorization: Bearer YOUR_KEY" # SMS activation format curl "https://virtualsns.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getBalance"
Service and country codes
Service codes are the names in our service page addresses, for example kakaotalk, line, wechat, zalo, naver, shopee and whatsapp. Country codes are ISO codes in lower case: kr, jp, id, ph, vn, th, us. GET /services and GET /countries return the full lists.
Typical flow
- Order a number with the service and the country. Save the id.
- Enter the number in the app and ask it to send the SMS.
- Read the order every 4 seconds until a code is there.
- Need one more SMS? Ask for another code, then read again. Done: finish the order.
- No code? Cancel for a full refund. Without a call, the refund happens by itself when the window ends.
Python
import os, time, requests
API = "https://virtualsns.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['VIRTUALSNS_KEY']}"}
order = requests.post(f"{API}/orders", headers=H,
data={"service": "kakaotalk", "country": "kr"}).json()["order"]
print("Use this number:", order["phone"])
while True:
o = requests.get(f"{API}/orders/{order['id']}", headers=H).json()["order"]
if o["code"] or o["status"] in ("refunded", "canceled"):
break
time.sleep(4)
print("Code:", o["code"])Node.js
const API = "https://virtualsns.com/api/v1";
const H = { Authorization: `Bearer ${process.env.VIRTUALSNS_KEY}` };
const { order } = await fetch(`${API}/orders`, {
method: "POST", headers: H,
body: new URLSearchParams({ service: "line", country: "jp" }),
}).then((r) => r.json());
console.log("Use this number:", order.phone);
let o = order;
while (!o.code && !["refunded", "canceled"].includes(o.status)) {
await new Promise((r) => setTimeout(r, 4000));
({ order: o } = await fetch(`${API}/orders/${order.id}`, { headers: H }).then((r) => r.json()));
}
console.log("Code:", o.code);Return error codes
REST API
Errors come as JSON: {"error":{"code","message"}} with these HTTP statuses:
| 400 | Missing or bad field (missing_filter, bad_json). |
| 401 | No key or a wrong key (no_key, bad_key). |
| 402 | Not enough credit (no_balance). |
| 404 | Unknown service, country, order or endpoint. |
| 409 | The order cannot do that now (has_code, not_ready, too_many_open, no_numbers). |
| 429 | More than 300 requests in a minute (rate_limited). |
SMS activation format
| BAD_KEY | Missing or wrong API key. |
| BAD_ACTION | Unknown action. |
| BAD_SERVICE | Unknown service code. |
| BAD_COUNTRY | The service is not sold in that country. |
| NO_BALANCE | Not enough credit. |
| NO_NUMBERS | No number available right now. Try again in a moment. |
| NO_ACTIVATION | Unknown activation id, or not yours. |
| EARLY_CANCEL_DENIED | A code has already arrived, so the activation cannot be canceled. |
| TOO_MANY_REQUESTS | More than 300 requests in a minute. |
| NO_ACTIVATIONS | 20 activations are already open. |
REST API methods
https://virtualsns.com/api/v1
GET/services
Every service code with its name, kind and lowest price. No key needed.
curl "https://virtualsns.com/api/v1/services"
{"services":[{"code":"kakaotalk","name":"KakaoTalk","category":"social","from":"0.06"}]}GET/countries
Every country code (ISO, lower case) with its name and dial code. No key needed.
curl "https://virtualsns.com/api/v1/countries"
{"countries":[{"code":"kr","name":"South Korea","dial_code":"82"}]}GET/prices
Prices in USD. Add service, country or both. No key needed.
curl "https://virtualsns.com/api/v1/prices?service=line&country=jp"
{"prices":[{"service":"line","country":"jp","price":"5.40"}]}GET/balance
Your credit in USD.
curl "https://virtualsns.com/api/v1/balance" \ -H "Authorization: Bearer YOUR_KEY"
{"balance":"25.00","currency":"USD"}POST/orders
Buys a number (201). Returns the order with the phone number and the time the window ends.
curl -X POST https://virtualsns.com/api/v1/orders \ -H "Authorization: Bearer YOUR_KEY" \ -d service=kakaotalk -d country=kr
{"order":{"id":"AC-7K2M9QX4PB","service":"kakaotalk","country":"kr","phone":"+821023456789","status":"waiting","code":null,"expires_at":"2026-11-03T12:20:00.000Z"},"window_minutes":20}GET/orders/AC-7K2M9QX4PB
One order with its status and every code received. Statuses: waiting, received, finished, refunded, canceled.
curl "https://virtualsns.com/api/v1/orders/AC-7K2M9QX4PB" \ -H "Authorization: Bearer YOUR_KEY"
{"order":{"id":"AC-7K2M9QX4PB","status":"received","code":"482193","sms":"[Kakao] Verification code [482193]"}}GET/orders
Your open orders (status=all for the last 100).
curl "https://virtualsns.com/api/v1/orders?status=open" \ -H "Authorization: Bearer YOUR_KEY"
{"orders":[...]}POST/orders/AC-7K2M9QX4PB/resend
Asks for another code on the same number, after the first code and while the window is open. No extra charge.
curl -X POST https://virtualsns.com/api/v1/orders/AC-7K2M9QX4PB/resend \ -H "Authorization: Bearer YOUR_KEY"
{"order":{"status":"received","waiting_for_resend":true}}POST/orders/AC-7K2M9QX4PB/finish
Closes an order that received its code.
curl -X POST https://virtualsns.com/api/v1/orders/AC-7K2M9QX4PB/finish \ -H "Authorization: Bearer YOUR_KEY"
{"order":{"status":"finished"}}POST/orders/AC-7K2M9QX4PB/cancel
Cancels before a code arrives. The full price goes back to your credit.
curl -X POST https://virtualsns.com/api/v1/orders/AC-7K2M9QX4PB/cancel \ -H "Authorization: Bearer YOUR_KEY"
{"order":{"status":"canceled","refunded":"8.40"}}SMS activation format methods
https://virtualsns.com/stubs/handler_api.php
Method getBalance
Your credit in USD.
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getBalance
ACCESS_BALANCE:12.50
Method getServicesList
Service codes you can buy (JSON).
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getServicesList
{"status":"success","services":[{"code":"line","name":"LINE"}]}Method getCountries
Country codes (ISO, lower case) and dial codes (JSON).
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getCountries
{"jp":{"name":"Japan","dial":"81"}}Method getPrices
Prices in USD per country and service. Both filters are optional.
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getPrices&service=line&country=jp
{"jp":{"line":{"cost":5.4,"count":100}}}Method getNumber
Buys a number. Returns the activation id and the number with its country code.
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getNumber&service=line&country=jp
ACCESS_NUMBER:AC-7K2M9QX4PB:819012345678
Method getStatus
STATUS_WAIT_CODE (no code yet), STATUS_OK:<code>, STATUS_WAIT_RETRY:<last code> (another code requested), STATUS_CANCEL (canceled or refunded).
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=getStatus&id=AC-7K2M9QX4PB
STATUS_OK:482913
Method setStatus
status=1 ready (ACCESS_READY), 3 another code (ACCESS_RETRY_GET), 6 finish (ACCESS_ACTIVATION), 8 cancel with a full refund while no code arrived (ACCESS_CANCEL).
GET https://virtualsns.com/stubs/handler_api.php?api_key=KEY&action=setStatus&id=AC-7K2M9QX4PB&status=3
ACCESS_RETRY_GET