₹ INR
₹INR
$USD
€EUR
₹0.00
U
User

User

—

Wallet
Gift Code
Settings
Sign Out
₹0.00
U

User

—

API Documentation

Integrate SastaSMS into your apps, bots, and scripts. Full programmatic access to buy numbers, get OTPs, manage orders, and check balance.

https://sastasms.pro/stubs/handler_api.php
Authentication: Pass your API key with every request as ?api_key=YOUR_KEY
Or via header: Authorization: Bearer YOUR_KEY  /  X-API-Key: YOUR_KEY
Format: Responses are plain text by default. Add &format=json to any request for a full JSON response.
Limits: 50 requests per second per API key by default (HTTP 429 with RATE_LIMIT and retry_after seconds). A number lives 20 minutes (expires_in = 1200).
🗝 Your API Key
Loading…
Activation API
GETaction=getNumber Buy a number & get activation details
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getNumber&service=tg&country=22&format=json
Alias: getNumberV2 also works — both return the same unified response.
You are charged only when a number is delivered; the amount is the price in the response. Every country has its own price (see getPrices) and maxPrice protects you from paying more than you expect. Country codes are our own ids (India = 22, Indonesia = 6, USA = 187), not phone dialling codes — get them from getCountries.
Parameters
ParamRequiredDescription
serviceRequiredService code (e.g. tg, wa). Get codes from getServicesList.
countryOptionalCountry code from getCountries (e.g. 22 = India). Omit (or any) to let us choose — the price is then the service's listed price (see getServicesList), which is often too low for a real number, so numbers are often unavailable. Pass a country for reliable results.
maxPriceOptionalHighest INR price you accept. If the price for this service/country is higher you get MAX_PRICE_EXCEEDED and nothing is charged.
operatorOptionalPin one price tier: use an id from operator_ids in getProviders. You are charged the price listed there for that tier. Omit to let us choose the best available tier at the country price.
formatOptionaljson for JSON (recommended). Default: plain text ACCESS_NUMBER:ID:PHONE.
JSON Response (&format=json)
{ "status": "OK", "order_id": 1234, "activation_id": "38496653", // use in getStatus & setStatus "number": "917991234567", "phone_number": "917991234567", "service": "Telegram", "service_code": "tg", "country": "India", "country_code": "22", "price": 18.50, // INR charged from your wallet "currency": "INR", "provider_id": 1, // internal id of the provider that served the number "multi_sms": false, // true = next OTP via setStatus status=3 "expires_in": 1200, // seconds until the order expires "cancel_lock": 120, // seconds after purchase before a cancel is accepted (see setStatus) "created_at_ts": 1792293000, // unix time of the purchase; "server_time" is our clock now "server_time": 1792293001, "note": null // admin note for this service if any }
Plain Text Response (legacy / default)
ACCESS_NUMBER:38496653:917991234567 ↑ activation_id ↑ phone number
Possible Errors
BAD_KEYNO_NUMBERSNO_BALANCEMAX_PRICE_EXCEEDEDOPERATION_NOT_AVAILABLEBAD_ACTIONRATE_LIMIT
Test this method now
Your API key: —
GETaction=setStatus Cancel, complete, or request next code
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=setStatus&id=ACTIVATION_ID&status=STATUS
Parameters
ParamRequiredDescription
idRequiredactivation_id from getNumber response
statusRequiredSee status codes below
Status Codes
ValueActionResponse
-1 or 8Cancel activation + refund walletACCESS_CANCEL
1Inform — SMS sent to numberACCESS_READY
3Wait for next SMS codeACCESS_RETRY_GET
6Complete activationACCESS_ACTIVATION
Cancel rules
• A number can be cancelled only while no SMS has arrived. Once a code is received the order is final (ALREADY_FINISHED).
• A cancel is accepted only after the cancel lock — the cancel_lock seconds returned by getNumber (it depends on the service, from about 15 s up to about 130 s — always read it from the response). Earlier than that you get EARLY_CANCEL_DENIED with wait_seconds; just call again after that time.
• A cancelled order is refunded to your wallet at once. An order that gets no SMS within expires_in seconds expires and is refunded automatically.
Possible Errors
BAD_STATUSNO_ACTIVATIONALREADY_FINISHEDEARLY_CANCEL_DENIEDCANCEL_FAILEDRETRY_FAILEDOPERATION_NOT_AVAILABLE
Test this method now
Your API key: —
GETaction=getStatus Poll OTP status & receive code
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getStatus&id=ACTIVATION_ID
Plain Text Response Values
STATUS_WAIT_CODESTATUS_OK:123456STATUS_CANCEL
Poll every 5 seconds. Stop at STATUS_OK or STATUS_CANCEL. Auto-refund on STATUS_CANCEL.
JSON Response (&format=json)
{ "status": "completed", // pending | waiting_next | completed | cancelled | expired "code": "123456", // latest code, null while waiting "text": "Your code is 123456", "sms": { "code": "123456", "text": "Your code is 123456" }, // null while waiting "all_codes": ["123456"], "all_sms": [ ... ], "number": "919812345678", "activation_id": "38496653", "order_id": 1234, "price": 120.96, "provider_id": 1, "can_get_next": false }
Test this method now
Your API key: —
GETaction=getStatusV2 Poll status — extended JSON response
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getStatusV2&id=ACTIVATION_ID
Same as getStatus with &format=json, but always returns JSON. While waiting "sms" is null; when a code arrives "sms" holds code and text. The status field is the order state: pending, waiting_next, completed, cancelled or expired.
{ "status": "pending", "code": null, "sms": null, "number": "919812345678", ... } // waiting { "status": "completed", "code": "123456", "sms": { "code": "123456", "text": "Your code is 123456" }, "number": "919812345678", ... } // received
Test this method now
Your API key: —
GETaction=getBalance Get wallet balance in INR
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getBalance
Plain Text Response
ACCESS_BALANCE:125.50
JSON Response (&format=json)
{ "status": "OK", "balance": 125.50, "currency": "INR" }
Test this method now
Your API key: —
Utility API
GETaction=getServicesList Services with listed price & availability
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getServicesList
Alias: getServices also works. Returns every active service with its listed price in INR, whether it is available, and whether it supports multiple SMS. Each country has its own price — read it with getPrices / getProviders.
Parameters
ParamRequiredDescription
serviceOptionalFilter by service code (e.g. tg). Omit for all services.
Response
{ "status": "OK", "total": 2863, "services": { "wa": { "code": "wa", "name": "Whatsapp", "price": 1.85, // the service's listed price in INR - other countries can cost more or less (see getPrices) "currency": "INR", "available": 999, // always 999 here (a fixed value) - use getPrices / getProviders for the stock of a country "provider_id": 1, "multi_sms": false, // true = can request next OTP via setStatus status=3 "expires_in": 1200 // seconds until an order expires } } }
All prices are in INR. price here is the service's listed price (usually the cheapest country); what you pay depends on the country, so read the country price with getPrices / getProviders and pass maxPrice to getNumber. Countries: getCountries.
Test this method now
Your API key: —
GETaction=getCountries List all countries with codes
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getCountries
Country codes are our own ids (India = 22, Indonesia = 6, USA = 187), not phone dialling codes. Use code as the country parameter of getNumber / getPrices. flag is the country's flag emoji. The entry 999999 (ANY_COUNTRY) is a placeholder, not a country — ignore it.
Parameters
ParamRequiredDescription
serviceOptionalOnly the countries that have a price for this service, e.g. wa. Omit for every country.
Response
{ "status": "OK", "total": 209, "countries": { // an object keyed by country code "22": { "code": "22", "name": "India", "flag": "🇮🇳" }, "6": { "code": "6", "name": "Indonesia", "flag": "🇮🇩" } } }
Test this method now
Your API key: —
GETaction=getPrices Price of every country for a service · also getPricesV2, getProviders
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getPrices&service=wa
Every country has its own price — look it up before you buy. Prices are in INR. Always pass service.
getPrices — price per country
{ "status": "OK", "data": { "22": { "wa": { "cost": 120.96, "count": 67100 } }, // country code -> service -> price in INR "6": { "wa": { "cost": 13.09, "count": 5000 } }, "*": { "wa": { "cost": 1.85, "count": 999 } } // "*" = the service's listed price } }
cost is the price of the cheapest tier in that country; count is the number of numbers in stock for that country, the same figure the website shows (0 = none right now; a country can be listed with 0 and getNumber then answers NO_NUMBERS and charges nothing). When there is no recent figure for the service, count is 999 = not known; the "*" row is always 999. Add &country=22 to get the price of one country only (getPricesV2 answers the same way); the getNumber charge for that country is this price (see getProviders for its tiers).
getProviders — the price tiers of one country
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getProviders&service=wa&country=6
{ "status": "OK", "service": "wa", "country": "6", "total": 15, "countries": [ { "country_code": "6", "country_name": "Indonesia", "price": 13.09, "qty": 999, "operator_ids": ["477"] }, { "country_code": "6", "country_name": "Indonesia", "price": 14.23, "qty": 999, "operator_ids": ["219"] } ] }
Each row is one price tier (qty = numbers in stock in that tier, as on the website; 999 = not known; 0 = none). Pass an id from its operator_ids as operator to getNumber to buy from exactly that tier at the price shown in its row; without it we pick the best available one. getPricesV2 answers {"status":"OK","data":{"<country>":{"<service>":{"<price>":999}}},"price":...,"currency":"INR"}.
GETaction=getOrders Your paginated order history
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getOrders&limit=10
Parameters
ParamRequiredDescription
limitOptionalResults per page. Omit for no limit — every matching order is returned. There is no maximum.
pageOptionalPage number (default 1). Only applies when limit is set.
statusOptionalpending | active | waiting_next | completed | api_cancelled | cancelled | expired. An order you cancel through the API is api_cancelled; cancelled is for orders cancelled in the dashboard.
Response
{ "status": "OK", "total": 890, "page": 1, "limit": 10, "total_pages": 89, "orders": [ { "order_id": 7775886, "activation_id": "aFu0KhKt1U9ZvKpp", "service_code": "wa", "service": "Whatsapp", "country_code": "22", "country": "India", "number": "919812345678", "code": null, "text": null, "all_sms": [], "price": 120.96, "currency": "INR", "status": "expired", "provider_id": 1, // pending | completed | api_cancelled | expired ... "created_at": "2026-10-16 16:33:20", "completed_at": "2026-10-16 16:53:54" } ] }
Test this method now
Your API key: —
GETaction=getActiveActivations Every open activation and its SMS — in one request
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=getActiveActivations
Returns all of your still-open activations together with any SMS already received — replacing one getStatus call per number with a single request. If you are holding 200 numbers, that is 1 request instead of 200.

There is no maximum. Called without parameters it returns every open activation you hold, however many that is.

Only activations from the last 20 minutes are returned — that is the lifetime of a number (expires_in is always 1200), so anything older has already expired. Pass max_age to widen that window.

Each item in activeActivations has exactly the same shape as a getStatusV2 response for a single activation, so existing per-order parsing code works unchanged — just loop over the array.
Parameters
ParamRequiredDescription
limitOptionalCap the number of rows. Omit for no limit (the default). There is no maximum.
serviceOptionalOnly activations for one service code, e.g. wa
include_completedOptional1 to also return recently completed orders (default 0). Still limited to the same time window.
max_ageOptionalTime window in minutes. Default 20 (a number's full lifetime), max 1440.
JSON Response
{ "status": "success", "total": 2, "limit": null, // null = no limit applied "max_age_minutes": 20, "server_time": "2026-08-25 20:16:45", "activeActivations": [ { "activationId": "581233040", "serviceCode": "tg", "phoneNumber": "919876543210", "activationCost": "32.37", "activationStatus": "STATUS_WAIT_CODE", // waiting "code": null, "text": null, "smsCount": 0, "allSms": [], "seconds_left": 900, "can_cancel": true }, { "activationId": "bVz5OIGBC1MaakqB", "serviceCode": "wa", "phoneNumber": "919812345678", "activationCost": "34.85", "activationStatus": "STATUS_OK:443112", // code received "code": "443112", "text": "Your WhatsApp code is 443112", "smsCount": 1, "allSms": [{"code": "443112", "text": "Your WhatsApp code is 443112", "time": "2026-09-02T10:54:14+05:30"}], "canGetAnotherSms": true, "seconds_left": 600, "can_cancel": true } ] }
Key fields
FieldDescription
activationStatusIdentical to what getStatus returns for that number: STATUS_WAIT_CODE, STATUS_OK:code or STATUS_CANCEL
allSmsFull SMS history, each entry with code, text and time. Populated only when more than one SMS has arrived — for a single SMS it is [] and code / text already hold it. Always an array, so looping is safe.
smsCountHow many SMS have arrived on this number
code / textThe latest code and its full message, or null while waiting. Some providers deliver only the OTP without the surrounding message — in that case text equals code.
seconds_leftSeconds remaining before the number expires. 0 once the order is finished and no further SMS can arrive.
can_canceltrue only while the order is still open (not completed, cancelled or expired) and the cancel lock has elapsed
canGetAnotherSmstrue if this number can still receive another SMS
dbStatusRaw order state: pending, active, waiting_next or completed
activationTimeWhen the number was bought (Y-m-d H:i:s, IST)
Empty list. When you hold no open activations the response is {"status":"NO_ACTIVATIONS","total":0,"activeActivations":[]} — check total or the array length rather than assuming status is always success.
Polling tip. Poll this once every few seconds instead of polling each activation separately. It reads from our database — which our servers keep continuously up to date — so it stays fast no matter how many numbers you hold.
Test this method now
Your API key: —
GETaction=regetNumber Get a new OTP on the same phone number (Multi-SMS only)
https://sastasms.pro/stubs/handler_api.php?api_key=YOUR_KEY&action=regetNumber&id=ACTIVATION_ID&format=json
Request a new OTP on the same phone number as a previously completed order. Only for services that support multiple OTPs (multi_sms: true). Charges the same price as the original order. Poll the returned new_activation_id with getStatus to receive the new OTP.
Parameters
ParamRequiredDescription
idRequiredActivation ID from a completed order that received an OTP.
formatOptionaljson for JSON (recommended). Default: plain text REGET_NUMBER_OK:NEW_ID:PHONE.
JSON Response (&format=json)
{ "status": "OK", "new_order_id": 74685, "new_activation_id": "Lw4S1r37abcXYZ", // poll with getStatus "number": "918595529925", "price": 13.34, // INR charged from your wallet "currency": "INR", "expires_in": 1200 // seconds until new order expires }
Plain Text Response (legacy / default)
REGET_NUMBER_OK:Lw4S1r37abcXYZ:918595529925 ↑ new_activation_id ↑ phone number
Possible Errors
NUMBER_STILL_ACTIVENO_ACTIVATIONBAD_ACTIONNO_BALANCEERROR
Test this method now
Your API key: —
Error Codes
BAD_KEY
Invalid or missing API key — api_key param not sent or key doesn't exist. Fix: Copy your key from the “Your API Key” card at the top of this page.
all
KEY_INACTIVE
API key exists but has been disabled by admin. Fix: Contact support to re-enable your key.
all
ACCOUNT_BANNED
Your account has been suspended — all API calls will be rejected. Fix: Contact support on Telegram @SastaSMS_Support for an appeal.
all
NO_BALANCE
Your wallet balance is too low to purchase this number. Fix: Add funds at Dashboard → Add Balance before calling getNumber.
getNumber getNumberV2
NO_NUMBERS
No numbers available for the requested service/country combination right now. Fix: Try a different country code, or retry after a few minutes.
getNumber getNumberV2
MAX_PRICE_EXCEEDED
The current number price is higher than the maxPrice you specified. Fix: Increase your maxPrice param, or omit it to accept any price.
getNumber getNumberV2
NO_ACTIVATION
The id (activation_id) was not found, or it belongs to a different account. Fix: Use the exact id returned by getNumber for this API key.
getStatus getStatusV2 setStatus
ALREADY_FINISHED
The order is already in a terminal state — completed, cancelled, or expired. No further actions are possible. Fix: Do not call setStatus on finished orders. Check status first with getStatus.
setStatus
BAD_STATUS
The status value sent is not a valid option for setStatus. Fix: Send the activation id and one of -1 / 8 (cancel), 1 (SMS sent), 3 (next code), 6 (complete). See setStatus above.
setStatus
EARLY_CANCEL_DENIED
The cancel lock has not elapsed yet — a number can only be cancelled some time after it was bought. The answer carries wait_seconds. Fix: Wait wait_seconds (see cancel_lock in the getNumber response) and call setStatus again.
setStatus
WINDOW_EXPIRED
The number's 20-minute window has closed, so a new code can no longer be requested. Fix: Buy a new number.
setStatus
BAD_STATE
The next code (status=3) is not allowed in the order's current state (cancelled or expired). Fix: Check the order with getStatus first.
setStatus
ALREADY_WAITING_NEXT
A request for the next code is already pending on this order. Fix: Keep polling getStatus for the new code.
setStatus
STATE_CHANGED
The order changed while your request was processed (for example a code arrived). Fix: Poll getStatusV2 and act on the current state.
setStatusgetStatus
BAD_ACTION
The action name is unknown or misspelled. Fix: Valid actions — getNumber, getNumberV2, regetNumber, getStatus, getStatusV2, setStatus, getBalance, getServicesList, getCountries, getPrices, getPricesV2, getProviders, getForexRate, getOrders, getActiveActivations. Also returned when a required parameter such as service or id is missing.
all
MISSING_PARAMS
A required parameter is missing from the request. Fix: Check the endpoint's param table above — all required fields must be included.
all
NO_ACTION
The action parameter is missing. The answer lists the available actions. Fix: Add &action=getBalance (or another action).
all
RATE_LIMIT / RATE_LIMIT_IP
Too many requests (50 per second per API key by default, also limited per IP). Sent with HTTP status 429 and retry_after seconds. Fix: Wait retry_after seconds. Poll getActiveActivations once instead of every order separately.
all
SERVER_BUSY
The server is momentarily at capacity. Nothing was done or charged. Fix: Retry in about 3 seconds.
all
CANCEL_FAILED
Cancel could not be recorded — the order may already be in a terminal state in the database. Fix: Call getStatus first to check current state before attempting cancel.
setStatus
RETRY_FAILED
Request for the next OTP (status=3) was rejected by the provider. Fix: The number may no longer be eligible for a retry. Cancel and get a new number.
setStatus
SERVER_ERROR
Unhandled internal exception — not caused by your request or input. Fix: Retry once. If it continues, contact support with the request timestamp.
all
OPERATION_NOT_AVAILABLE
We could not complete the operation right now (provider busy or unreachable). When buying a number you have not been charged. Fix: Retry after a few seconds; if it persists try another country.
getNumbergetNumberV2getStatussetStatus