OTPGet API Docs –
SMS OTP, Rental & Email
Buy virtual phone numbers for OTP verification, rent long-term SMS numbers across 200+ countries, and get temporary Gmail addresses — all via one simple REST API.
All requests must include your API Key in the query string.
Base URL: https://otpget.com/stubs/handler_api.php
| # | Action | Key Params | Description |
|---|---|---|---|
| 1 | getBalance | — | Get wallet balance |
| 2 | getCountries | type | List countries by provider (1–4) |
| 3 | getServices | country, type | List services for a country |
| 4 | getNumber | service, country, type | Buy a virtual number for OTP |
| 5 | getStatus | id | Poll for received SMS code |
| 6 | setStatus | id, status | Complete (6), retry (3) or cancel & refund (8) |
Check your account balance in PKR by entering this URL in your browser.
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getBalance';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getBalance"}
print(requests.get(url, params=params).text)
List all available countries. You can filter by provider type (1, 2, 3, or 4).
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getCountries&type=1';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getCountries", "type": "1"}
print(requests.get(url, params=params).text)
"1": [{"id": "1", "name": "Russia"}, ...],
"2": [{"id": "1", "name": "USA"}, ...],
...
}
Get available services for a specific country and provider.
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getServices&country=1&type=1';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getServices", "country": "1", "type": "1"}
print(requests.get(url, params=params).text)
"tg": "Telegram - 45 PKR",
"wa": "WhatsApp - 60 PKR"
}
Order a new phone number to receive SMS. This will deduct PKR from your balance.
| Parameter | Type | Description |
|---|---|---|
| service | string | e.g., 'tg', 'wa' |
| country | int | Country ID from list |
| type | int | Provider (1-4) |
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getNumber&service=tg&country=1&type=1';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getNumber", "service": "tg", "country": "1", "type": "1"}
print(requests.get(url, params=params).text)
ACCESS_NUMBER:$order_id:$phone
Check if an SMS has been received for an order ID.
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=getStatus&id=YOUR_ORDER_ID';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "getStatus", "id": "YOUR_ORDER_ID"}
print(requests.get(url, params=params).text)
STATUS_WAIT_CODE
STATUS_OK:$code
Cancel an activation for a refund or complete a successful one.
$url = 'https://otpget.com/stubs/handler_api.php?api_key=' . $apiKey . '&action=setStatus&id=YOUR_ORDER_ID&status=8';
echo file_get_contents($url);
url = "https://otpget.com/stubs/handler_api.php"
params = {"api_key": "YOUR_KEY", "action": "setStatus", "id": "YOUR_ORDER_ID", "status": "8"}
print(requests.get(url, params=params).text)
| Status Code | Meaning |
|---|---|
| 3 | Request another SMS (Retry) |
| 6 | Complete Activation (Success) |
| 8 | Cancel and Refund (Only if no SMS received) |
Base URL: https://otpget.com/stubs/rental-handler.php
| # | Action | Required Params | Description |
|---|---|---|---|
| 1 | getRentalCountries | — (optional: provider) | List all countries available for rental |
| 2 | getRentalPricing | country_code, provider | Get pricing tiers for a country |
| 3 | getAvailableRentals | country_code, provider | Live stock availability check |
| 4 | rentNumber | country_code, provider, duration_hours | Buy a rental number |
| 5 | getMyRentals | — | List all your rentals |
| 6 | getRentalSMS | order_id | Fetch SMS messages on a rented number |
| 7 | renewRental | rental_id, duration_hours | Extend rental period |
provider=1 = Server 1 | provider=2 = Server 2duration_hours values:
12 = 12 Hours · 24 = 1 Day · 168 = 1 Week · 720 = 1 Month · 4320 = 6 Months · 8640 = 12 Months
List all countries available for rental. Filter by provider or omit to get all servers.
| Parameter | Required | Description |
|---|---|---|
| provider | Optional | 1 = Server 1 | 2 = Server 2. Omit to get both. |
$data = json_decode(file_get_contents($url), true);
foreach($data['countries'] as $c) {
echo $c['name'] . ' (' . $c['country_code'] . ')' . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"getRentalCountries","provider":"2"})
for c in r.json()['countries']:
print(c['name'], c['country_code'])
{"id":"1","provider":"2","name":"Canada","country_code":"ca"},
{"id":"2","provider":"2","name":"UNITED KINGDOM","country_code":"gb"},
{"id":"6","provider":"2","name":"United States of America","country_code":"us"}
]}
Get all available pricing tiers for a country. Use duration_hours from this response when buying or renewing.
| Parameter | Required | Description |
|---|---|---|
| country_code | Required | Country code from getRentalCountries e.g. ca, us |
| provider | Required | 1 = Server 1 | 2 = Server 2 |
$data = json_decode(file_get_contents($url), true);
foreach($data['pricing'] as $p) {
echo $p['duration_hours'] . 'h — ' . $p['price'] . ' PKR' . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"getRentalPricing","country_code":"ca","provider":"2"})
for p in r.json()['pricing']:
print(p['duration_hours']+'h —', p['price'], 'PKR')
{"id":"1","duration_hours":"720","duration_preset":"oneMonth","price":"840.00","country_name":"Canada"},
{"id":"2","duration_hours":"4320","duration_preset":"sixMonths","price":"5040.00","country_name":"Canada"},
{"id":"3","duration_hours":"8640","duration_preset":"twelveMonths","price":"10080.00","country_name":"Canada"}
]}
Check live stock availability for a country before buying. Returns number of available numbers and minimum rental duration.
| Parameter | Required | Description |
|---|---|---|
| country_code | Required | e.g. ca, us, gb |
| provider | Required | 1 = Server 1 | 2 = Server 2 |
$data = json_decode(file_get_contents($url), true);
foreach($data['available'] as $a) {
echo $a['area_title'] . ': ' . $a['available'] . ' numbers available' . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"getAvailableRentals","country_code":"ca","provider":"2"})
for a in r.json()['available']:
print(a['area_title'], a['available'], 'available')
{"area_code":"ca","area_title":"Canada","unit_price":200,"available":3338,"min_month":1}
]}
Purchase a phone number for rental. All three parameters are required. Check getRentalPricing first to confirm valid duration_hours values for your country.
| Parameter | Required | Description |
|---|---|---|
| country_code | Required | Country code e.g. ca, us, gb |
| provider | Required | 1 = Server 1 | 2 = Server 2 |
| duration_hours | Required | Rental duration: 12, 24, 168, 720, 4320, 8640 |
$data = json_decode(file_get_contents($url), true);
if($data['status'] == '200') {
echo 'Phone: ' . $data['phone'] . PHP_EOL;
echo 'Order ID: ' . $data['order_id'] . PHP_EOL;
echo 'Expires: ' . $data['expires'] . PHP_EOL;
echo 'Balance: ' . $data['new_balance'] . ' PKR' . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={
"api_key":"YOUR_KEY","action":"rentNumber",
"country_code":"ca","provider":"2","duration_hours":"720"
})
d = r.json()
if d['status'] == '200':
print('Phone:', d['phone'], '| Expires:', d['expires'])
"phone":"3434337545","order_id":"2673093356180000583",
"server":"Server 2","duration_hours":720,
"price_paid":"840.00","new_balance":"4220.00",
"expires":"2026-04-09 21:55:55"}
order_id to fetch SMS later. Save id from getMyRentals to renew.
List all your rented numbers — active and expired. Use order_id to fetch SMS. Use id to renew.
$data = json_decode(file_get_contents($url), true);
foreach($data['rentals'] as $r) {
echo $r['phone_number'] . ' | ' . $r['status'] . ' | expires: ' . $r['expiry_time'] . PHP_EOL;
// use $r['id'] for renewRental
// use $r['order_id'] for getRentalSMS
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"getMyRentals"})
for rental in r.json()['rentals']:
print(rental['phone_number'], rental['status'], rental['expiry_time'])
"id":"27",
"server":"Server 2",
"phone_number":"3434337545",
"order_id":"2673093356180000583",
"status":"active",
"country_code":"ca",
"country_name":"Canada",
"duration_hours":"720",
"price_paid":"840.00",
"expiry_time":"2026-04-09 21:55:55"
}]}
Fetch all SMS messages received on a rented number. Use order_id from rentNumber or getMyRentals.
| Parameter | Required | Description |
|---|---|---|
| order_id | Required | The order_id from rentNumber or getMyRentals |
$data = json_decode(file_get_contents($url), true);
foreach($data['messages'] as $msg) {
echo 'From: ' . $msg['from'] . PHP_EOL;
echo 'Code: ' . $msg['code'] . PHP_EOL;
echo 'Text: ' . $msg['text'] . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"getRentalSMS","order_id":"YOUR_ORDER_ID"})
for msg in r.json()['messages']:
print('Code:', msg['code'], '| Text:', msg['text'])
"from":"Server 2",
"text":"<#> Your WhatsApp Business code 740-279",
"code":"",
"timestamp":"2026-03-09T20:57:32Z"
}]}
Extend the rental period on an active number. Use id from getMyRentals as rental_id. The new expiry is calculated from the current expiry time (not today).
| Parameter | Required | Description |
|---|---|---|
| rental_id | Required | The id field from getMyRentals |
| duration_hours | Required | Extension duration: 12, 24, 168, 720, 4320, 8640 |
$data = json_decode(file_get_contents($url), true);
if($data['status'] == '200') {
echo 'New expiry: ' . $data['new_expiry'] . PHP_EOL;
echo 'New balance: ' . $data['new_balance'] . ' PKR' . PHP_EOL;
}
r = requests.get("https://otpget.com/stubs/rental-handler.php", params={"api_key":"YOUR_KEY","action":"renewRental","rental_id":"5","duration_hours":"720"})
d = r.json()
if d['status'] == '200':
print('New expiry:', d['new_expiry'], '| Balance:', d['new_balance'])
"rental_id":27,
"duration_hours":720,
"new_balance":"3440.00","new_expiry":"2026-05-09 21:55:55"}
Buy temporary email addresses from services like Gmail, Telegram, Instagram and 60+ others. All email endpoints use the same base URL below.
Returns all available email services with their names, prices (in your account currency), and current stock count. Optionally filter by domain.
| Parameter | Type | Description |
|---|---|---|
| domain | string | Optional. Email domain to filter. Default: gmail.comOptions: gmail.com · mailnestpro.com · hihinail.com · flytempbox.com · mailburstx.com |
$url = 'https://otpget.com/stubs/email_handler.php?api_key=' . $apiKey . '&action=getEmailServices&domain=gmail.com';
$response = file_get_contents($url);
$data = json_decode($response, true);
foreach($data['services'] as $svc) {
echo $svc['service_name'] . ' — ' . $svc['price'] . ' (stock: ' . $svc['count'] . ')' . PHP_EOL;
}
url = "https://otpget.com/stubs/email_handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailServices", "domain": "gmail.com"}
data = requests.get(url, params=params).json()
for svc in data['services']:
print(svc['service_name'], '-', svc['price'])
"status": "200",
"count": 65,
"services": [
{"service_code": "ig", "service_name": "Instagram", "price": 120.00, "count": 48},
{"service_code": "tg", "service_name": "Telegram", "price": 95.00, "count": 120},
{"service_code": "fb", "service_name": "Facebook", "price": 110.00, "count": 60},
...
]
}
Purchase a temporary email address for a specific service. The price is deducted from your wallet. Returns the email_id and the actual email address to use.
| Parameter | Type | Description |
|---|---|---|
| service_id | string | Required. Service code from getEmailServices e.g. ig, tg, fb |
| domain | string | Optional. Email domain. Default: gmail.com |
$url = 'https://otpget.com/stubs/email_handler.php?api_key=' . $apiKey . '&action=buyEmail&service_id=ig&domain=gmail.com';
$data = json_decode(file_get_contents($url), true);
if($data['status'] == '200') {
echo 'Email: ' . $data['email'] . PHP_EOL;
echo 'Email ID: ' . $data['email_id'] . PHP_EOL;
echo 'Price: ' . $data['price'] . ' | New Balance: ' . $data['balance'];
}
url = "https://otpget.com/stubs/email_handler.php"
params = {"api_key": "YOUR_KEY", "action": "buyEmail", "service_id": "ig", "domain": "gmail.com"}
data = requests.get(url, params=params).json()
if data['status'] == '200':
print('Email:', data['email'])
print('Email ID:', data['email_id'])
"status": "200",
"message": "Email activated successfully",
"email_id": "7291834",
"email": "temp.abc123@gmail.com",
"service": "Instagram",
"domain": "gmail.com",
"price": 120.00,
"balance": 4880.00
}
"status": "500",
"message": "Insufficient balance. Need: 120.00"
}
Poll this endpoint after buying an email to retrieve the verification code / OTP that arrives in the inbox. Call every 5–10 seconds until a code is received.
| Parameter | Type | Description |
|---|---|---|
| email_id | string | Required. The email_id returned from buyEmail |
$emailId = 'YOUR_EMAIL_ID';
$url = 'https://otpget.com/stubs/email_handler.php?api_key=' . $apiKey . '&action=getEmailCode&email_id=' . $emailId;
// Poll every 5 seconds for up to 2 minutes
for($i = 0; $i < 24; $i++) {
$data = json_decode(file_get_contents($url), true);
if($data['status'] == '200' && !empty($data['messages'])) {
echo 'OTP: ' . $data['messages'][0]['code'];
break;
}
sleep(5);
}
url = "https://otpget.com/stubs/email_handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailCode", "email_id": "YOUR_EMAIL_ID"}
for _ in range(24): # poll for 2 minutes
data = requests.get(url, params=params).json()
if data['status'] == '200' and data.get('messages'):
print('OTP:', data['messages'][0]['code'])
break
time.sleep(5)
"status": "200",
"email_id": "7291834",
"messages": [
{
"email": "temp.abc123@gmail.com",
"subject": "Verification Code",
"body": "Your verification code is 847293",
"code": "847293"
}
]
}
200 Code received |
202 Still waiting (keep polling) |
300 Cancelled
Cancel an email activation. Behavior depends on whether an OTP was already received:
| Situation | Result |
|---|---|
| OTP already received | Order marked complete — OTP code returned. No refund (job was done). |
| Still waiting for OTP | Activation cancelled on provider + full refund to your wallet. |
| Already cancelled | Returns success (safe to call multiple times). |
| Parameter | Type | Description |
|---|---|---|
| email_id | string | Required. The email_id returned from buyEmail |
$url = 'https://otpget.com/stubs/email_handler.php?api_key=' . $apiKey . '&action=cancelEmail&email_id=YOUR_EMAIL_ID';
$data = json_decode(file_get_contents($url), true);
if ($data['status'] == '200') {
echo $data['message'] . PHP_EOL;
if (isset($data['code'])) echo 'OTP Code: ' . $data['code'] . PHP_EOL;
if (isset($data['refunded'])) echo 'Refunded: ' . $data['refunded'] . PHP_EOL;
if (isset($data['balance'])) echo 'New Balance: ' . $data['balance'] . PHP_EOL;
}
url = "https://otpget.com/stubs/email_handler.php"
params = {"api_key": "YOUR_KEY", "action": "cancelEmail", "email_id": "YOUR_EMAIL_ID"}
data = requests.get(url, params=params).json()
print(data['message'])
if 'code' in data: print('OTP Code:', data['code'])
if 'refunded' in data: print('Refunded:', data['refunded'], '| Balance:', data['balance'])
"status": "200",
"message": "Order completed - OTP was already received",
"code": "847293",
"email": "temp.abc@gmail.com"
}
"status": "200",
"message": "Cancelled and refunded",
"refunded": 120.00,
"balance": 5120.00
}
Retrieve your past email purchases with their status, service used, domain, price and timestamp. Supports pagination.
| Parameter | Type | Description |
|---|---|---|
| page | int | Optional. Page number for pagination. Default: 1. Returns 20 records per page. |
$url = 'https://otpget.com/stubs/email_handler.php?api_key=' . $apiKey . '&action=getEmailHistory&page=1';
$data = json_decode(file_get_contents($url), true);
echo 'Total orders: ' . $data['total'] . PHP_EOL;
foreach($data['history'] as $h) {
echo $h['email_address'] . ' | ' . $h['service_id'] . ' | ' . $h['status'] . PHP_EOL;
}
url = "https://otpget.com/stubs/email_handler.php"
params = {"api_key": "YOUR_KEY", "action": "getEmailHistory", "page": "1"}
data = requests.get(url, params=params).json()
print('Total:', data['total'])
for h in data['history']:
print(h['email_address'], '|', h['service_id'], '|', h['status'])
"status": "200",
"total": 42,
"page": 1,
"history": [
{
"email_id": "7291834",
"email_address": "temp.abc123@gmail.com",
"service_id": "ig",
"service_name": "Instagram",
"domain": "gmail.com",
"status": "active",
"code": "",
"price": 120.00,
"created_at": "2026-03-09 14:22:00"
}
]
}
| Status Value | Meaning |
|---|---|
| active | Email is active, waiting for OTP or in use |
| received | OTP code was received — code field contains it |
| cancelled | Manually cancelled via cancelEmail |
Base URL: https://otpget.com/stubs/email_handler.php
| # | Action | Key Params | Description |
|---|---|---|---|
| 13 | getEmailServices | domain | List services + prices + stock |
| 14 | buyEmail | service_id, domain | Buy temp email — returns email_id |
| 15 | getEmailCode | email_id | Poll for OTP (200=got it, 202=waiting, 300=cancelled) |
| 16 | cancelEmail | email_id | Cancel & refund if no OTP yet; complete if OTP received |
| 17 | getEmailHistory | page | Paginated purchase history |
| — | getBalance | — | Wallet balance (works on both APIs) |
Error Codes
All three APIs (SMS OTP, Rental, Email) return consistent JSON error responses. Use the status field to detect errors programmatically.
"status": "401",
"message": "BAD_KEY"
}
| Response | HTTP | When it happens |
|---|---|---|
| BAD_KEY | — | API key missing, invalid or belongs to blocked account |
| ACCOUNT_BLOCKED | — | Your account has been suspended by admin |
| BAD_ACTION | — | Unknown action parameter sent |
| BAD_SERVICE | — | Service code not found for given country/type |
| BAD_COUNTRY | — | Country ID not found or missing |
| BAD_TYPE | — | Provider type must be 1, 2, 3 or 4 |
| NO_BALANCE | — | Insufficient wallet balance to buy number |
| NO_ACTIVATION | — | Order ID not found or does not belong to you |
| NO_NUMBERS | — | Provider has no stock for this service/country |
| STATUS_CANCEL | — | Activation already cancelled (on setStatus call) |
| STATUS_WAIT_CODE | — | SMS not received yet — keep polling getStatus |
| STATUS_OK:CODE | — | SMS received — code is after the colon |
| ERROR_PRICE_CHANGE | — | Provider price increased above your balance — number auto-cancelled |
| ERROR_PROVIDER_1..4 | — | Upstream provider returned unexpected response |
| status | message | When it happens |
|---|---|---|
| 401 | BAD_KEY | Invalid API key |
| 403 | ACCOUNT_BLOCKED | Account suspended |
| 500 | country_code and provider required | Missing required params on getRentalPricing / getAvailableRentals |
| 404 | No pricing available for this country | No pricing exists for the given country_code + provider on rentNumber |
| 500 | NO_BALANCE | Insufficient balance to rent number |
| 500 | Server 1/2 is currently disabled | Provider disabled by admin |
| 500 | Server 1/2 Error: … | Upstream rental provider error — message has detail |
| 500 | Active rental not found | Invalid rental_id on renewRental |
| 500 | No pricing for this renewal duration | Duration not available for that country/provider |
| 500 | Rental not found or access denied | Wrong order_id on getRentalSMS |
| status | message | When it happens |
|---|---|---|
| 401 | BAD_KEY | Invalid or missing API key |
| 403 | ACCOUNT_BLOCKED | Account suspended by admin |
| 400 | BAD_ACTION | Unknown action value |
| 400 | service_id is required | Missing service_id on buyEmail |
| 400 | email_id is required | Missing email_id on getEmailCode / cancelEmail |
| 402 | Insufficient balance. Need: X — Have: Y | Balance too low to buy email |
| 404 | Service not available for this domain | Service/domain combo not offered by provider |
| 404 | No stock available for this service | Provider has 0 emails left for this service |
| 404 | Email activation not found | Wrong email_id or belongs to another user |
| 409 | Code already received — cannot cancel | OTP was received; use complete flow instead |
| 500 | API connection error | Cannot reach mail API |
| 500 | No email available: … | Api returned error on purchase |
| 500 | Database error. Email cancelled. | DB failed after API success — email auto-cancelled |
| 503 | Email service not configured | Admin has not set the mail API key |
| 503 | Email service is currently disabled | Admin disabled email service temporarily |
| 200 | — | Success on all actions |
| 202 | Waiting for code... | getEmailCode: OTP not arrived yet — keep polling |
| 300 | Cancelled / Cancelled by provider | getEmailCode / cancelEmail: activation was cancelled |