Phone verification is the backbone of account security — but building it yourself means juggling SIMs, dealing with SMS gateways, and handling edge cases like expired codes and failed deliveries. A SMS verification API abstracts all of that away: you request a number, the user triggers a code, you fetch the OTP programmatically, and you verify the signup. Done.
This developer guide walks through the AgoVerify SMS Verification API — what it offers, how to authenticate, and working code examples for renting a number and retrieving an OTP.
What the AgoVerify API Offers
- Rent a virtual number for any supported service and country
- Retrieve the received OTP programmatically once it arrives
- Check order status and auto-cancel/refund on failure
- Manage account balance and transaction history
- Place SMM orders (followers, likes, views) via the same API
- Rate-limited, authenticated with API keys — safe for production
Full interactive documentation is available at /api/docs, and a Postman collection ships in docs/agoverify-api-postman.json.
Authentication
Every request is authenticated with an API key. Generate and rotate keys from the developer dashboard. Pass your key in the request header:
Authorization: Bearer YOUR_API_KEY
Accept: application/json
All endpoints are rate-limited per key. Hitting the limit returns 429 Too Many Requests with a Retry-After header.
Core Flow: Rent a Number and Get an OTP
The typical verification flow has three steps:
1. Rent a number
POST /api/v1/numbers
Content-Type: application/json
{
"service": "whatsapp",
"country": "us"
}
Response:
{
"order_id": 10245,
"number": "+12025550173",
"service": "whatsapp",
"country": "us",
"status": "pending",
"expires_at": "2026-08-23T18:05:00Z"
}
2. Trigger the SMS on the target platform
Hand number to your user (or your test harness) and have the target platform send the OTP to it. This step happens outside the API.
3. Poll for the OTP
GET /api/v1/numbers/10245
Response once the SMS arrives:
{
"order_id": 10245,
"number": "+12025550173",
"status": "completed",
"code": "372914",
"received_at": "2026-08-23T18:02:11Z"
}
If the rental window expires with no SMS, the order moves to cancelled and the balance is refunded automatically — no extra call needed.
Code Example: PHP with Guzzle
$apiKey = 'YOUR_API_KEY';
$base = 'https://agoverify.com/api/v1';
// 1. Rent a number for WhatsApp in the US
$rent = $client->post("$base/numbers", [
'headers' => ['Authorization' => "Bearer $apiKey"],
'json' => ['service' => 'whatsapp', 'country' => 'us'],
]);
$order = json_decode($rent->getBody(), true);
echo "Number: {$order['number']}\n";
// 2. Poll until the OTP arrives (or the order expires)
while (true) {
sleep(5);
$status = $client->get("$base/numbers/{$order['order_id']}", [
'headers' => ['Authorization' => "Bearer $apiKey"],
]);
$res = json_decode($status->getBody(), true);
if ($res['status'] === 'completed') {
echo "OTP: {$res['code']}\n";
break;
}
if ($res['status'] === 'cancelled') {
echo "No SMS received — refunded.\n";
break;
}
}
Code Example: Python with requests
import requests, time
API_KEY = "YOUR_API_KEY"
BASE = "https://agoverify.com/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Rent a number
order = requests.post(f"{BASE}/numbers",
headers=HEADERS,
json={"service": "whatsapp", "country": "us"},
).json()
print(f"Number: {order['number']}")
# Poll for the OTP
while True:
time.sleep(5)
res = requests.get(f"{BASE}/numbers/{order['order_id']}", headers=HEADERS).json()
if res["status"] == "completed":
print(f"OTP: {res['code']}")
break
if res["status"] == "cancelled":
print("No SMS — refunded.")
break
Best Practices for Production
- Don't poll too aggressively. 5-second intervals are a good balance. The rental window is short, so don't sleep too long either.
- Handle
cancelledgracefully. Auto-refunds happen server-side — just retry with a different country if a number fails. - Store
order_idso you can reconcile status later, even after your polling loop exits. - Keep your API key secret. Use environment variables or a secrets manager — never commit it to a repo.
- Respect rate limits. On
429, back off using theRetry-Afterheader. - Validate the service/country combo before presenting it to users — not every service is available in every country.
Use Cases
- Phone-verified signups for your own app without storing real user numbers
- Automated test accounts for QA across hundreds of services
- Marketing at scale — create verified accounts per client or campaign
- Reseller platforms — build your own number-rental storefront on top of the API
- SMM automation — combine number rental with the SMM order endpoints to run full growth campaigns
Frequently Asked Questions
How long is the rental window?
Typically a few minutes — enough to receive a single OTP. The exact window is returned in expires_at on the rental response.
What happens if no SMS arrives?
The order auto-cancels at expiry and your balance is refunded. No support ticket required.
Can I rent the same number again?
Numbers are released after each rental. For persistent 2FA, use a long-term virtual line or your own SIM.
Is there a sandbox?
Use the lowest-cost service/country combo to test the flow end-to-end with minimal spend. Full interactive docs are at /api/docs.
Start Building
Generate an API key from the developer dashboard, grab the interactive docs, and ship phone-verified signups in an afternoon. The AgoVerify SMS Verification API handles the SIMs, gateways, and failover — you focus on your product.
Join our community
Follow us on social media for updates & support