The future of
OTP verification.
Integrate the world's most reliable virtual & long-term rental number API. One endpoint, JSON everywhere.
Every request — temp number or rental — must include your API Key in the query string.
Every single response — success or error — is JSON. There is no plain-text response anywhere in this API. The two endpoints use slightly different envelopes, so check which one you're calling:
SMS OTP API — /stubs/handler_api.php
SUCCESSRental API — /stubs/rental-handler.php
SUCCESSHTTP status codes are meaningful on both endpoints too (401 bad key, 402 insufficient balance, 404 not found, 502 upstream error) — but always check the JSON body (success or status) first, not just the HTTP code.
Check your account balance in PKR by entering this URL in your browser.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getBalance';
$res = json_decode(file_get_contents($url), true);
echo $res['data']['balance'];
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getBalance"}
print(requests.get(url, params=params).json())
Lists every provider type (1-7) and whether it's currently active — check this before assuming a given type value has any countries/services behind it.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getServers';
$res = json_decode(file_get_contents($url), true);
foreach ($res['data'] as $s) { echo $s['name'] . ' — ' . ($s['active'] ? 'active' : 'inactive') . PHP_EOL; }
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getServers"}
print(requests.get(url, params=params).json())
{ "type": "1", "name": "Server 1", "active": true },
{ "type": "2", "name": "Server 2", "active": true },
{ "type": "5", "name": "Server 5", "active": true },
{ "type": "6", "name": "Server 6", "active": false },
{ "type": "7", "name": "Server 7", "active": true }
] }
List all available countries for temp numbers. You can filter by provider type (1-7). See Get Servers below to discover which types are currently active.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getCountries&type=1';
$res = json_decode(file_get_contents($url), true);
print_r($res['data']);
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getCountries", "type": "1"}
print(requests.get(url, params=params).json())
"success": true,
"action": "getCountries",
"data": {
"1": [{"id": "1", "name": "Russia"}, ...],
"2": [{"id": "1", "name": "USA"}, ...]
}
}
Get available services for a specific country and provider.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getServices&country=1&type=1';
$res = json_decode(file_get_contents($url), true);
print_r($res['data']);
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getServices", "country": "1", "type": "1"}
print(requests.get(url, params=params).json())
"success": true,
"action": "getServices",
"data": [
{ "id": "12", "name": "Telegram", "price": "45.00" },
{ "id": "13", "name": "WhatsApp", "price": "60.00" }
]
}
Order a new phone number to receive SMS. This will deduct PKR from your balance.
| Parameter | Type | Description |
|---|---|---|
| service | string | Service id from Get Services |
| country | int | Country/server id from Get Countries |
| type | int | Provider (1-7), default 1 |
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getNumber&service=$SERVICE_ID&country=$COUNTRY_ID&type=$PROVIDER_ID';
$res = json_decode(file_get_contents($url), true);
if ($res['success']) { echo $res['data']['phone']; }
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getNumber", "service": "1", "country": "1", "type": "1"}
print(requests.get(url, params=params).json())
"success": true,
"action": "getNumber",
"data": { "order_id": "a1b2c3...", "phone": "923001234567", "price": "45.00" }
}
Check if an SMS has been received for an order ID.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getStatus&id=YOUR_ORDER_ID';
$res = json_decode(file_get_contents($url), true);
echo $res['data']['status'];
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getStatus", "id": "YOUR_ORDER_ID"}
print(requests.get(url, params=params).json())
Cancel an activation for a refund or complete a successful one.
$url = 'https://www.smsglock.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=setStatus&id=YOUR_ORDER_ID&status=8';
$res = json_decode(file_get_contents($url), true);
echo $res['data']['status'];
url = "https://www.smsglock.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "setStatus", "id": "YOUR_ORDER_ID", "status": "8"}
print(requests.get(url, params=params).json())
| Status Code | Meaning |
|---|---|
| 3 / 6 | Complete Activation (Success — only once an SMS/code has been received) |
| 8 | Cancel and Refund (only allowed 2 minutes after purchase) |
Long-term numbers you keep for weeks or months, instead of a single OTP. This is a separate endpoint from the SMS OTP API above — same api_key, different base URL and a different response shape.
Every response here uses a status string ("200" for success, an error code otherwise) rather than the success/data shape used by the SMS OTP API:
List all countries available for long-term number rentals.
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=getRentalCountries';
$data = json_decode(file_get_contents($url), true);
foreach ($data['countries'] as $c) { echo $c['name'] . ' (' . $c['country_code'] . ')' . PHP_EOL; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getRentalCountries"}
print(requests.get(url, params=params).json())
{"id":"1","provider":"1","name":"Canada","country_code":"ca"},
{"id":"3","provider":"1","name":"United States of America","country_code":"us"}
]}
Get all available duration/price tiers for a country.
| Parameter | Required |
|---|---|
| country_code | Yes |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=getRentalPricing&country_code=us';
$data = json_decode(file_get_contents($url), true);
foreach ($data['pricing'] as $p) { echo $p['duration_hours'] . 'h — ' . $p['price'] . ' PKR' . PHP_EOL; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getRentalPricing", "country_code": "us"}
print(requests.get(url, params=params).json())
{"id":"7","duration_hours":"720","price":"2520.00","country_name":"United States of America"},
{"id":"8","duration_hours":"4320","price":"15120.00","country_name":"United States of America"}
]}
Live stock check for a country before buying.
| Parameter | Required |
|---|---|
| country_code | Yes |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=getAvailableRentals&country_code=us';
echo file_get_contents($url);
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getAvailableRentals", "country_code": "us"}
print(requests.get(url, params=params).json())
{"area_code":"us","area_title":"United States of America","available":3338,"min_month":1}
]}
Purchase a phone number for rental. Check getRentalPricing first to confirm a valid duration_hours.
| Parameter | Required |
|---|---|
| country_code | Yes |
| duration_hours | Yes — 720, 4320 or 8640 |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=rentNumber&country_code=us&duration_hours=720';
$data = json_decode(file_get_contents($url), true);
if ($data['status'] == '200') { echo 'Phone: ' . $data['phone'] . PHP_EOL . 'Order ID: ' . $data['order_id']; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "rentNumber", "country_code": "us", "duration_hours": "720"}
print(requests.get(url, params=params).json())
"phone":"3434337545","order_id":"2673093356180000583","server":"Server 1",
"duration_hours":720,"price_paid":"2520.00","new_balance":"4220.00",
"expires":"2026-10-02 21:55:55"}
List all your rented numbers. Use order_id to fetch SMS. Use id to renew.
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=getMyRentals';
$data = json_decode(file_get_contents($url), true);
foreach ($data['rentals'] as $r) { echo $r['phone_number'] . ' | ' . $r['status'] . PHP_EOL; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getMyRentals"}
print(requests.get(url, params=params).json())
"id":"27","server":"Server 1","phone_number":"3434337545",
"order_id":"2673093356180000583","status":"active",
"country_code":"us","country_name":"United States of America",
"duration_hours":"720","price_paid":"2520.00","expiry_time":"2026-10-02 21:55:55"
}]}
Fetch all SMS messages received on a rented number. Use order_id from rentNumber or getMyRentals.
| Parameter | Required |
|---|---|
| order_id | Yes |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=getRentalSMS&order_id=YOUR_ORDER_ID';
$data = json_decode(file_get_contents($url), true);
foreach ($data['messages'] as $msg) { echo 'Code: ' . $msg['code'] . ' | Text: ' . $msg['text'] . PHP_EOL; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getRentalSMS", "order_id": "YOUR_ORDER_ID"}
print(requests.get(url, params=params).json())
"from":"Server 1","text":"Your WhatsApp code 740-279","code":"740279","timestamp":"2026-09-02T20:57:32Z"
}]}
Extend the rental period on an active number. Use id from getMyRentals as rental_id.
| Parameter | Required |
|---|---|
| rental_id | Yes — the id field from getMyRentals |
| duration_hours | Yes |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=renewRental&rental_id=27&duration_hours=720';
$data = json_decode(file_get_contents($url), true);
if ($data['status'] == '200') { echo 'New expiry: ' . $data['new_expiry']; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "renewRental", "rental_id": "27", "duration_hours": "720"}
print(requests.get(url, params=params).json())
"phone_number":"3434337545","duration_hours":720,
"price_paid":"2520.00","new_balance":"1700.00","new_expiry":"2027-04-02 21:55:55"}
Cancel an active rental for a refund — only available within 20 minutes of purchase. This actually cancels the number with the upstream provider (not just a local flag) — the refund only happens once that succeeds. Use id from getMyRentals as rental_id.
| Parameter | Required |
|---|---|
| rental_id | Yes — the id field from getMyRentals |
$url = 'https://www.smsglock.com/stubs/rental-handler.php?api_key=' . $apiKey . '&action=cancelRental&rental_id=27';
$data = json_decode(file_get_contents($url), true);
if ($data['status'] == '200') { echo 'Refunded: ' . $data['refunded']; }
url = "https://www.smsglock.com/stubs/rental-handler.php"
params = {"api_key": "YOUR_KEY", "action": "cancelRental", "rental_id": "27"}
print(requests.get(url, params=params).json())
"refunded":"2520.00","new_balance":"4220.00"}
Temporary email addresses for OTP verification. A third, separate endpoint from SMS OTP and Rental — same api_key, own base URL and response shape.
Every request needs api_key, action, and server (1 or 2, default 1):
| Server | Flow |
|---|---|
| 1 | Service-based — e.g. Instagram/Telegram codes on gmail.com. Needs service_id + domain. |
| 2 | Domain-based — e.g. gmail.com, mail.com, gmx.com. Needs domain + site. Supports reorderEmail for a fresh code on the same mailbox. |
Response shape, same convention as Rental:
200 success · 202 still waiting · 300 cancelled · anything else is an error.
Server 1: services available for a domain. Server 2: domains available for a site.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=getEmailServices&server=1&domain=gmail.com';
$data = json_decode(file_get_contents($url), true);
foreach ($data['services'] as $s) { echo $s['service_name'] . ' — ' . $s['price'] . PHP_EOL; }
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailServices", "server": "1", "domain": "gmail.com"}
print(requests.get(url, params=params).json())
Server 1 needs service_id + domain. Server 2 needs domain + site.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=buyEmail&server=1&service_id=ig&domain=gmail.com';
$data = json_decode(file_get_contents($url), true);
if ($data['status'] == '200') { echo 'Email: ' . $data['email'] . ' | ID: ' . $data['email_id']; }
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "buyEmail", "server": "1", "service_id": "ig", "domain": "gmail.com"}
print(requests.get(url, params=params).json())
| Parameter | Server 1 | Server 2 |
|---|---|---|
| service_id | Required (e.g. ig, tg) | Not used |
| domain | Optional (default gmail.com) | Required (e.g. gmail.com, mail.com) |
| site | Not used | Optional — site you're registering on (e.g. telegram.com) |
Poll every 5–10 seconds after buying to retrieve the verification code.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=getEmailCode&email_id=7291834';
for ($i=0; $i<24; $i++) {
$data = json_decode(file_get_contents($url), true);
if ($data['status']=='200') { echo 'Code: ' . $data['messages'][0]['code']; break; }
sleep(5);
}
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailCode", "email_id": "7291834"}
print(requests.get(url, params=params).json())
Cancel an activation. If a code already arrived, this completes it instead. If still waiting, it cancels and refunds.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=cancelEmail&email_id=7291834';
echo file_get_contents($url);
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "cancelEmail", "email_id": "7291834"}
print(requests.get(url, params=params).json())
Request a fresh code on the same mailbox — the order stays open, it does not close/finish it. Only for Server 2 emails that already received a code. After a successful reorder the order flips back to "waiting" so you can poll getEmailCode again.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=reorderEmail&server=2&email_id=7291834';
echo file_get_contents($url);
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "reorderEmail", "server": "2", "email_id": "7291834"}
print(requests.get(url, params=params).json())
Retrieve your past email purchases. Paginated, 20 per page.
$url = 'https://www.smsglock.com/stubs/email-handler.php?api_key=' . $apiKey . '&action=getEmailHistory&page=1';
$data = json_decode(file_get_contents($url), true);
foreach ($data['history'] as $h) { echo $h['email_address'] . ' | ' . $h['status'] . PHP_EOL; }
url = "https://www.smsglock.com/stubs/email-handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailHistory", "page": "1"}
print(requests.get(url, params=params).json())
Error Codes
SMS OTP API — /stubs/handler_api.php
| Code | Description |
|---|---|
| BAD_KEY | Missing or invalid API key. |
| ACCOUNT_BLOCKED | This account is suspended. |
| BAD_ACTION | Missing or unrecognized action. |
| BAD_COUNTRY / BAD_SERVICE / BAD_TYPE / BAD_ID / BAD_STATUS | A required parameter is missing, invalid, or has no matching record. |
| NO_BALANCE | Insufficient wallet balance for this purchase. |
| NO_WALLET | No wallet record found for this account. |
| NO_ACTIVATION | No activation found for this id on this account. |
| EARLY_CANCEL_DENIED | Numbers can only be cancelled 2 minutes after purchase. |
| NO_SMS_RECEIVED | Cannot finish the order — no SMS/code received yet. |
| STATUS_ALREADY_CHANGED | This activation was already finalized (finished or cancelled). |
| PROVIDER_NOT_CONFIGURED | The selected server has no credentials configured on this account. |
| ERROR_PROVIDER_1-4 | The upstream server returned an error — see message for details. |
Rental API — /stubs/rental-handler.php
| status | message | When it happens |
|---|---|---|
| 401 | Invalid API key / API key is required. | Missing or invalid api_key |
| 403 | Account is blocked or inactive. | Account suspended |
| 400 | Unknown action / a required param is missing / Cancel window expired. | Bad or missing action, country_code, duration_hours, etc. — or cancelRental called more than 20 minutes after purchase |
| 402 | Insufficient balance. | Wallet balance too low |
| 404 | No pricing found… / Rental not found… | No pricing for that country/duration, or wrong rental_id/order_id |
| 503 | Server 1 is currently unavailable/disabled. | Rentals switched off in admin settings |
| 502 | Server 1 error: … | Upstream error — see message |
| 500 | Database error: … | DB transaction failed — balance not deducted |
Email OTP API — /stubs/email-handler.php
| status | When it happens |
|---|---|
| 401 | Invalid or missing API key |
| 403 | Account suspended by admin |
| 400 | Missing/unknown action, or a required param (service_id, domain, email_id) is missing |
| 402 | Insufficient balance |
| 404 | Service/domain not available, or email activation not found |
| 500 | Server 1/2 connection error, or database error |
| 503 | Email service not configured or disabled |
| 200 | Success on all actions |
| 202 | getEmailCode: still waiting — keep polling |
| 300 | Activation was cancelled (by you or by the provider) |