Developer API
SMS verification from your own code
One HTTPS call gives your bot or platform a real number for WhatsApp, Telegram and many more services. Read the code by webhook or long polling, and pay only for numbers that get one.
- 1,321services
- 145countries
- $0.10minimum price per number
- Autorefund when no code arrives
curl
curl -s -X POST https://smsgrab.com/api/dev/v1/activations \
-H "Authorization: Bearer $SMSGRAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service":"whatsapp","country":"indonesia"}'
Python
activation = requests.post(
"https://smsgrab.com/api/dev/v1/activations",
headers={"Authorization": f"Bearer {key}"},
json={"service": "whatsapp", "country": "indonesia"},
).json()
Node.js
const activation = await fetch('https://smsgrab.com/api/dev/v1/activations', {
method: 'POST',
headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ service: 'whatsapp', country: 'indonesia' }),
}).then((response) => response.json());
PHP
$activation = json_decode((string) $client->post('activations', [
'json' => ['service' => 'whatsapp', 'country' => 'indonesia'],
])->getBody(), true);
Go
order := map[string]any{"service": "whatsapp", "country": "indonesia"}
err := call("POST", "/activations", order, idempotencyKey(), &activation)
{
"id": "5c1d0c2e-9f3a-4b7e-8a61-2f0c9d4e7b10",
"compat_id": 100000123,
"status": "WAITING_SMS",
"service_id": "whatsapp",
"country_id": "indonesia",
"phone_number": "+6281234567890",
"price_minor": 18,
"currency": "USD",
"expires_at": "2026-09-27T10:25:00.000Z",
"sms": []
}
Built for automation
Everything your integration needs, with the same stock, ledger and refunds as the app.
-
Clean REST API
Predictable JSON, idempotent purchases and clear error reasons you can act on.
-
Signed webhooks
HMAC-signed events for every code and status change, with retries for 24 hours.
-
Long polling
Hold a request for up to 30 seconds and get the code the moment it arrives.
-
sms-activate compatible
Point your existing tools at one new address. The actions and answers stay the same.
-
Keys you control
Read-only or buying keys, IP allowlists, daily spend caps, expiry and zero-downtime rotation.
-
Automatic refunds
No code before the number expires? The charge goes straight back to your balance.
-
Usage and request log
Daily requests, spend and errors per key, plus a searchable log of the last 7 days.
-
Volume prices
Prices built on wholesale cost that drop automatically as your monthly volume grows.
Live in four steps
Your first number is only a few calls away.
-
Create an account
Sign up with your e-mail address and verify it. The app and the website share the same account.
-
Create an API key
Choose its access, restrict it to your servers and copy the secret once.
-
Buy a number
POST the service and the country. You get the number and its price at once.
-
Receive the code
Wait with long polling or a webhook, then finish the activation.
Prices that fall as you grow
Developer prices start from the wholesale cost of each number plus a markup that shrinks with your 30-day volume.
- Never more than the price of the same number in the app
- At least $0.10 per number
- Numbers without a code are refunded automatically
- Your tier updates within minutes of reaching it
- Charged in USD from the same balance as the app
Markup by 30-day developer spend
| 30-day developer spend | Markup on wholesale | Example price |
|---|---|---|
| Below $100.00 | +80% | $0.18 28% below the app |
| $100.00 and more | +70% | $0.17 32% below the app |
| $500.00 and more | +60% | $0.16 36% below the app |
| $2,000.00 and more | +50% | $0.15 40% below the app |
Example: an offer with a wholesale cost of $0.10 that costs $0.25 in the app.
Migration
Switch from sms-activate in one line
Our compatible endpoint speaks the same protocol, so bots and panels built for sms-activate work after you change the base address and the key.
https://smsgrab.com/api/stubs/handler_api.php
- getNumber, getStatus, setStatus, getPrices and every other standard action
- Numeric activation ids, service codes and country ids you already use
- The same keys, limits, prices, refunds and webhooks as the REST API
curl
BASE="https://smsgrab.com/api/stubs/handler_api.php?api_key=$SMSGRAB_API_KEY"
curl -s "$BASE&action=getBalance"
curl -s "$BASE&action=getNumber&service=tg&country=6"
curl -s "$BASE&action=getStatus&id=100000123"
curl -s "$BASE&action=setStatus&id=100000123&status=6"
Python
import os
import requests
BASE = "https://smsgrab.com/api/stubs/handler_api.php"
KEY = os.environ["SMSGRAB_API_KEY"]
def action(name: str, **params) -> str:
response = requests.get(BASE, params={"api_key": KEY, "action": name, **params}, timeout=30)
response.raise_for_status()
return response.text
print(action("getBalance"))
answer = action("getNumber", service="tg", country=6)
if answer.startswith("ACCESS_NUMBER:"):
_, activation_id, number = answer.split(":")
print(activation_id, number)
Real time
Codes pushed to your server
Subscribe to the events you care about and we deliver them to your HTTPS endpoint with a signature you can check.
- Number bought
- Code received
- Activation completed
- Activation cancelled
- Activation expired
- Charge refunded
- Balance running low
- Every delivery is signed with HMAC-SHA256 and a timestamp
- Only public HTTPS endpoints, checked before every delivery
- Test deliveries, a 30-day history and one-click redelivery
Developer questions
How much does the developer API cost?
There is no subscription. Each number costs its wholesale price plus a markup of 80%, which drops to 70%, 60% and 50% as your 30-day developer spend passes 100, 500 and 2,000 USD. A number is never below 0.10 USD and never above its app price.
What happens if no code arrives?
A number lives 20 minutes. If no code arrives in that time, or you cancel while it is still waiting, the charge is refunded to your balance automatically.
Can I use my existing sms-activate integration?
Yes. Replace the base address with our compatible endpoint and use your SmsGrab key. The standard actions, answers and numeric ids stay the same.
What are the rate limits?
By default each key can make 600 requests and 60 purchases per minute, all keys of an account together 3,000 requests per minute, and up to 100 numbers can wait for a code at once.
How do I keep my key safe?
Keep keys on your servers only, give each app its own key, restrict it to your server addresses and set a daily spend cap. If a key may have leaked, rotate or revoke it from your account.
Do the app and the API share one balance?
Yes. The API uses the balance of your SmsGrab account, and every purchase and refund shows up in your wallet like any other.
More answers are in the help center