Integrate virtual numbers into your software: authentication, getNumber, getStatus and setStatus flows, error handling, with Python and Node.js examples.
What the API does
The SMSFlash API lets your own software buy a number, wait for the SMS and read the code automatically. It is useful for QA teams testing OTP sign-up flows in many countries, for tools and bots, and for resellers. The format follows the widely used SMS-activation protocol, so many existing tools work after you change the base URL and API key. See also using the SMSFlash API.
Authentication and endpoint
Create a key in Profile, API key. Every request is a GET or POST to /stubs/handler_api.php with api_key and action. Keep the key secret: it spends your balance. If it leaks, regenerate it in Profile and the old key stops working immediately.
Actions
getBalancereturnsACCESS_BALANCE:12.50getServicesListandgetCountriesreturn JSON lists with service codes and country IDsgetPrices&service=tgreturns cost and stock per countrygetNumber&service=tg&country=6returnsACCESS_NUMBER:<id>:<phone>. AddmaxPriceto cap the price.getNumberV2is the same, but returns JSON with activationId, phoneNumber, activationCost and end timegetStatus&id=<id>returnsSTATUS_WAIT_CODE,STATUS_OK:<code>orSTATUS_CANCELsetStatus&id=<id>&status=8cancels and refunds (before a code);status=6completes;status=3asks for another SMS where supportedgetActiveActivationslists your open orders
Common errors: BAD_KEY, NO_BALANCE, NO_NUMBERS, BAD_SERVICE, NO_ACTIVATION, BAD_STATUS.
Python example
import time, requests
BASE = "https://smsflash.org/stubs/handler_api.php"
KEY = "sf_your_key"
def call(**p):
p["api_key"] = KEY
return requests.get(BASE, params=p, timeout=20).text
r = call(action="getNumber", service="tg", country="6")
if not r.startswith("ACCESS_NUMBER"):
raise SystemExit(r) # NO_NUMBERS, NO_BALANCE ...
_, act_id, phone = r.split(":")
print("Use this number:", phone)
for _ in range(60): # about 10 minutes
s = call(action="getStatus", id=act_id)
if s.startswith("STATUS_OK"):
print("Code:", s.split(":", 1)[1])
call(action="setStatus", id=act_id, status=6)
break
time.sleep(10)
else:
call(action="setStatus", id=act_id, status=8) # cancel + refundNode.js example
const BASE = "https://smsflash.org/stubs/handler_api.php";
const KEY = process.env.SMSFLASH_KEY;
const call = async (p) => (await fetch(BASE + "?" + new URLSearchParams({ api_key: KEY, ...p }))).text();
const r = await call({ action: "getNumber", service: "wa", country: "6" });
if (!r.startsWith("ACCESS_NUMBER")) throw new Error(r);
const [, id, phone] = r.split(":");
console.log("Number", phone);
for (let i = 0; i < 60; i++) {
const s = await call({ action: "getStatus", id });
if (s.startsWith("STATUS_OK")) { console.log("Code", s.slice(10)); await call({ action: "setStatus", id, status: 6 }); break; }
await new Promise((ok) => setTimeout(ok, 10000));
}Good practice
- Poll
getStatusevery 5 to 10 seconds, not faster. The API allows up to 120 requests per minute per IP. - Always cancel (status 8) numbers you no longer need, so you get a refund.
- Handle
NO_NUMBERSby trying another country or retrying later. - Send
maxPriceso you never pay more than you expect. - Never commit the key to public repositories.
Get a numberCreate free account
Frequently asked questions
Is the API compatible with existing SMS-activation software?
Yes. It follows the common handler_api protocol (getNumber, getStatus, setStatus), so most tools only need the new URL and key.
Does the API cost extra?
No. API orders cost the same as orders on the website, and refunds work the same way.
How do I find service codes and country IDs?
Call getServicesList and getCountries. They return JSON with every code and ID you can use in getNumber.