The OTP API that gets out of your way.
Bearer keys, predictable JSON, honest status codes. Rent a number, poll for the code, finish or cancel — with automatic refunds when an SMS never arrives.
curl -X POST https://otpbolt.com/api/v1/activations \ -H "Authorization: Bearer $OTPBOLT_KEY" \ -H "Content-Type: application/json" \ -d '{"service":"openai","country":"us"}' { "id": "5f0c2a9e4b1d7c3a9e2f6b10", "status": "pending", "phone": "+12015550123", "price_cents": 41, "expires_at": "2026-10-30T10:32:00+00:00" }
Authentication
Create a key in Dashboard → Developers. Keys start with ob_live_ and are shown once. Send it on every request:
Authorization: Bearer ob_live_xxxxxxxxxxxxxxxxxxxx
Rate limits follow your plan: Spark 30 req/min, Volt 120 req/min, Surge and Storm 600 req/min.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/balance | Wallet balance, plan, rate limit |
| GET | /api/v1/countries | Country ids + dial codes |
| GET | /api/v1/services?country=us | Services in a country with your price and stock |
| GET | /api/v1/price?service=telegram&country=gb | Price for one pair |
| POST | /api/v1/activations | Rent a number {"service","country"} |
| GET | /api/v1/activations/{id} | Poll status + code |
| POST | /api/v1/activations/{id}/retry | Request another SMS |
| POST | /api/v1/activations/{id}/finish | Close a successful rental |
| POST | /api/v1/activations/{id}/cancel | Cancel before any SMS (refund) |
| GET | /api/v1/numbers | Your dedicated numbers |
| GET | /api/v1/numbers/{id}/messages?since_id=0 | Inbox of a dedicated number |
Activation statuses
pending → received → finished, or cancelled / expired (both refunded automatically).
Errors
Errors return JSON {"error":{"code":"…","message":"…"}}. Branch on code: invalid_api_key (401), insufficient_funds (402, includes shortfall_c), out_of_stock / too_early / no_retry (409), account_locked (423), rate_limited (429).
Node.js example
const API = "https://otpbolt.com/api/v1";
const H = { Authorization: `Bearer ${process.env.OTPBOLT_KEY}`, "Content-Type": "application/json" };
const act = await (await fetch(`${API}/activations`, { method: "POST", headers: H,
body: JSON.stringify({ service: "telegram", country: "us" }) })).json();
for (;;) {
const a = await (await fetch(`${API}/activations/${act.id}`, { headers: H })).json();
if (a.status === "received") { console.log(a.code); break; }
if (["cancelled", "expired"].includes(a.status)) throw new Error("refunded");
await new Promise(r => setTimeout(r, 4000));
}
More: the full API guide and Playwright CI walkthrough.
Ship your verification tests today.
Create an account, generate a key and make your first call in minutes.