SMS Verification API
Use the BinOTP API to rent virtual phone numbers, receive OTP codes and cancel orders from your own app or script. Every endpoint returns JSON and authenticates with your API key.
Quick Start
https://binotp.com/api/v1X-API-Key: YOUR_API_KEY
?apikey=... still works so existing integrations keep running, but it is not recommended: a key in the URL gets recorded in server logs, browser history and the Referer header.Limits and notes
- 60 requests per minute per API key, across all endpoints. Going over returns error 429.
- Up to 5 orders can wait for a code at the same time.
- Call get-sms about every 5 seconds — polling faster won't make the code arrive sooner.
- If an order expires without a code, get-sms returns status "expired" and the refunded field shows the amount returned to your balance.
Code examples
Rent a Google (opt4) number in the US, then check for the code every 5 seconds until there is a result.
# 1. Rent a Google (opt4) number in the US
curl -X POST "https://binotp.com/api/v1/rent-number" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service": "opt4", "country": "US"}'
# 2. Check for the SMS code (repeat every 5 seconds until status is not "waiting_sms")
curl "https://binotp.com/api/v1/get-sms?orderId=ORDER_ID" \
-H "X-API-Key: YOUR_API_KEY"import time
import requests
API = "https://binotp.com/api/v1"
HEADERS = {"X-API-Key": "YOUR_API_KEY"}
# 1. Rent a Google (opt4) number in the US
order = requests.post(API + "/rent-number", headers=HEADERS,
json={"service": "opt4", "country": "US"}).json()
if not order["success"]:
raise SystemExit(order["error"])
print("Phone:", order["phone"])
# 2. Poll for the code every 5 seconds
while True:
sms = requests.get(API + "/get-sms", headers=HEADERS,
params={"orderId": order["orderId"]}).json()
if not sms["success"]:
raise SystemExit(sms["error"])
if sms["status"] != "waiting_sms":
print(sms["status"], sms.get("smsCode"))
break
time.sleep(5)// Node.js 18+ (built-in fetch), run as an ES module
const API = "https://binotp.com/api/v1";
const headers = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };
// 1. Rent a Google (opt4) number in the US
const order = await fetch(API + "/rent-number", {
method: "POST",
headers,
body: JSON.stringify({ service: "opt4", country: "US" }),
}).then((r) => r.json());
if (!order.success) throw new Error(order.error);
console.log("Phone:", order.phone);
// 2. Poll for the code every 5 seconds
while (true) {
const sms = await fetch(API + "/get-sms?orderId=" + order.orderId, { headers })
.then((r) => r.json());
if (!sms.success) throw new Error(sms.error);
if (sms.status !== "waiting_sms") {
console.log(sms.status, sms.smsCode);
break;
}
await new Promise((resolve) => setTimeout(resolve, 5000));
}<?php
$api = "https://binotp.com/api/v1";
$headers = ["X-API-Key: YOUR_API_KEY", "Content-Type: application/json"];
function call($method, $url, $headers, $body = null) {
$ch = curl_init($url);
$options = [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
];
if ($body !== null) {
$options[CURLOPT_POSTFIELDS] = json_encode($body);
}
curl_setopt_array($ch, $options);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
return $result;
}
// 1. Rent a Google (opt4) number in the US
$order = call("POST", $api . "/rent-number", $headers, ["service" => "opt4", "country" => "US"]);
if (!$order["success"]) exit($order["error"]);
echo "Phone: " . $order["phone"] . PHP_EOL;
// 2. Poll for the code every 5 seconds
do {
sleep(5);
$sms = call("GET", $api . "/get-sms?orderId=" . $order["orderId"], $headers);
} while ($sms["success"] && $sms["status"] === "waiting_sms");
echo $sms["success"] ? $sms["status"] . " " . ($sms["smsCode"] ?? "") : $sms["error"];Endpoints
8/api/v1/meGet account info
Returns your balance and account information.
apikeystringRequiredYour API key{ "success": true, "balance": 10.00, "email": "user@example.com", "username": "demo" }/api/v1/servicesList available services
Returns all active OTP services.
apikeystringRequiredYour API key{ "success": true, "services": [{ "code": "opt4", "name": "Google" }, ...] }/api/v1/countriesList available countries
Returns all supported countries.
apikeystringRequiredYour API key{ "success": true, "countries": [{ "code": "US", "name": "United States", "flagEmoji": "🇺🇸" }, ...] }/api/v1/pricesGet prices
Returns pricing for services. Optionally filter by service and country code.
apikeystringRequiredYour API keyservicestringOptionalService code (e.g. opt4)countrystringOptionalCountry code (e.g. US){ "success": true, "prices": [{ "service": "opt4", "serviceName": "Google", "country": "US", "price": 0.35 }] }/api/v1/rent-numberRent a phone number
Purchases a virtual phone number for OTP. Deducts balance automatically.
apikeystringRequiredYour API keyservicestringRequiredService code (e.g. opt4 for Google)countrystringRequiredCountry code (e.g. US)maxPricenumberOptionalMaximum price you accept (USD). If the current price is higher, the order is rejected and nothing is charged.{ "success": true, "orderId": "abc123", "phone": "12025551234", "service": "opt4", "country": "US", "price": 0.35, "expiresAt": "..." }/api/v1/get-smsCheck for SMS code
Poll this endpoint to check if an OTP code has been received. Auto-refunds on expiry.
apikeystringRequiredYour API keyorderIdstringRequiredOrder ID from rent-number{ "success": true, "orderId": "abc123", "phone": "12025551234", "smsCode": "123456", "status": "completed" }/api/v1/cancelCancel order
Cancels an active order and refunds your balance.
apikeystringRequiredYour API keyorderIdstringRequiredOrder ID to cancel{ "success": true, "orderId": "abc123", "refunded": 0.35, "status": "cancelled" }/api/v1/ordersOrder history
List your past orders with pagination.
apikeystringRequiredYour API keylimitnumberOptionalResults per page (default 10, max 100)offsetnumberOptionalSkip N results (for pagination){ "success": true, "orders": [...], "total": 42, "limit": 10, "offset": 0 }Error codes
On error the API returns one of the HTTP codes below with a JSON body where success is false and error describes the problem (always in English):
{ "success": false, "error": "Insufficient balance" }Missing service or country codeA required parameter is missing or invalid.Insufficient balanceYour balance is too low — top up and try again.Temporarily out of stock, please try againNo numbers available right now for this service/country — retry later or pick another country.Price is $0.25 which exceeds your maxPrice of $0.20…The current price is above your maxPrice — raise maxPrice or check /prices.Invalid or missing API keyThe API key is missing or wrong, or the account is disabled.Order not foundThere is no such order in your account.Cannot cancel: SMS code already received…The order already has a code, so it can't be cancelled — call get-sms to read it.Cannot cancel yet: please wait about 2 minutes after purchase…Cancelling is not possible right after purchase — retry in a few minutes.Too many requests. Limit: 60/minMore than 60 requests per minute.You already have 5 active orders (max 5)…Too many orders waiting for a code — wait for codes or expiry, or cancel some.Cannot cancel yet: please wait … minute(s) after purchase…Cancelling is not possible right after purchase — retry in a few minutes.Service temporarily unavailableThe service is temporarily unavailable — retry later.