API Documentation
Integrate SastaOTP into your apps, bots, and scripts. Full programmatic access to buy numbers, get OTPs, manage orders, and check balance.
https://sastaotp.com/stubs/handler_api.php
Authentication: Pass your API key with every request as
Or via header:
Format: Responses are plain text by default. Add
?api_key=YOUR_KEYOr via header:
Authorization: Bearer YOUR_KEY / X-API-Key: YOUR_KEYFormat: Responses are plain text by default. Add
&format=json to any request for a full JSON response.
🗝 Your API Key
Loading…
Activation API
GETaction=getNumber
Buy a number & get activation details
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getNumber&service=tg&country=91&format=json
Alias:
getNumberV2 also works — both return the same unified response.Parameters
| Param | Required | Description |
|---|---|---|
| service | Required | Service code (e.g. tg, wa). Get codes from getServicesList. |
| country | Optional | Country code (e.g. 91). Omit for auto-select. |
| maxPrice | Optional | Max INR price. Returns MAX_PRICE_EXCEEDED if current price is higher. |
| operator | Optional | Pin a specific country — use country_code from getServicesList → countries[]. |
| format | Optional | json 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": "91",
"price": 18.50, // INR charged from your wallet
"multi_sms": false, // true = next OTP via setStatus status=3
"can_get_another_sms": false,
"expires_in": 1200, // seconds until order expires
"note": null // admin note for this service if any
}
Plain Text Response (legacy / default)
ACCESS_NUMBER:38496653:917991234567
↑ activation_id ↑ phone number
Possible Errors
Test this method now
Your API key: —
GETaction=setStatus
Cancel, complete, or request next code
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=setStatus&id=ACTIVATION_ID&status=STATUS
Parameters
| Param | Required | Description |
|---|---|---|
| id | Required | activation_id from getNumber response |
| status | Required | See status codes below |
Status Codes
| Value | Action | Response |
|---|---|---|
| -1 or 8 | Cancel activation + refund wallet | ACCESS_CANCEL |
| 1 | Inform — SMS sent to number | ACCESS_READY |
| 3 | Wait for next SMS code | ACCESS_RETRY_GET |
| 6 | Complete activation | ACCESS_ACTIVATION |
Test this method now
Your API key: —
GETaction=getStatus
Poll OTP status & receive code
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getStatus&id=ACTIVATION_ID
Plain Text Response Values
Poll every 5 seconds. Stop at
STATUS_OK or STATUS_CANCEL. Auto-refund on STATUS_CANCEL.
Test this method now
Your API key: —
GETaction=getStatusV2
Poll status — extended JSON response
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getStatusV2&id=ACTIVATION_ID
Same as
getStatus but always returns JSON. Waiting returns "sms": null; code received returns full SMS object.{ "verificationType": 2, "sms": null } // waiting
{ "verificationType": 2, "sms": { "code": "123456", "text": "123456" } } // received
Test this method now
Your API key: —
GETaction=getBalance
Get wallet balance in INR
https://sastaotp.com/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 live price, providers & availability
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getServicesList
Alias:
getServices also works. Returns every active service with its live INR price, provider info, multi-SMS support flag, and per-country provider breakdown — all in one call.Parameters
| Param | Required | Description |
|---|---|---|
| service | Optional | Filter by service code (e.g. tg). Omit for all services. |
Response
{
"status": "OK",
"total": 120,
"services": {
"tg": {
"code": "tg",
"name": "Telegram",
"logo": "https://...",
"price": 18.50, // your selling price in INR
"currency": "INR",
"available": 8420, // numbers in stock right now
"multi_sms": false, // true = can request next OTP via setStatus status=3
"expires_in": 1200, // seconds until order expires
"countries": [ // available countries with prices
{
"country_code": "91",
"country_name": "India",
"flag": "🇮🇳",
"price": 18.50,
"qty": 999
}
]
}
}
}
All prices in INR — commission included. Use
countries[].country_code as country in getNumber to buy from a specific country.
Test this method now
Your API key: —
GETaction=getCountries
List all countries with codes
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getCountries
{"status":"OK","countries":[{"id":91,"eng":"India","code":"91"}],"total":180}
Test this method now
Your API key: —
GETaction=getOrders
Your paginated order history
https://sastaotp.com/stubs/handler_api.php?api_key=YOUR_KEY&action=getOrders&limit=10
Parameters
| Param | Required | Description |
|---|---|---|
| limit | Optional | Results per page (default 20, max 100) |
| page | Optional | Page number (default 1) |
| status | Optional | pending | completed | cancelled | expired |
Test this method now
Your API key: —
GETaction=regetNumber
Get a new OTP on the same phone number (Multi-SMS only)
https://sastaotp.com/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
| Param | Required | Description |
|---|---|---|
| id | Required | Activation ID from a completed order that received an OTP. |
| format | Optional | json 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
Test this method now
Your API key: —
Error Codes
Authentication Errors
BAD_KEY
Invalid or missing API key —
api_key param not sent or key doesn't exist.
Fix: Copy your key from Dashboard → Settings → API Key.
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@sastaotp.com for appeal.
all
Balance & Availability Errors
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
SERVICE_UNAVAILABLE
The requested service is not available for that country at this time.
Fix: Check /getServicesList to see which country codes are supported.
getNumber
getNumberV2
Order & State Errors
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: Use status=6 (cancel) or status=1 (received). See setStatus docs above.
setStatus
Request Errors
BAD_ACTION
The
action name is unknown or misspelled.
Fix: Valid actions — getNumber, getNumberV2, getStatus, getStatusV2, setStatus, getBalance, getPrices, getServicesList, getCountries, getOrders.
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
ERROR_SQL
Internal database error — not caused by your request.
Fix: Retry once. If it persists, contact support with the timestamp of the failed call.
all
Provider & Runtime Errors
PROVIDER_ERROR
The upstream provider (Grizzly/Meow) returned an unexpected response while buying a number.
Fix: Retry after a few seconds. If persistent, try a different country or service.
getNumber
getNumberV2
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