100MB FREEResidential proxiesClaim
Docs/Public & Account API

Public & Account API

Integrate virtual phone numbers for SMS reception directly into your software. For the reseller-specific API (sub-users, markup, payouts), see the Reseller API Reference.

1Authentication

Endpoints that act on your account (buying a number, checking usage) require an API key from Developer → API Keys, passed as a Bearer token:

Authorization: Bearer notp_1234567890abcdef

/v1/public/* endpoints (prices, services, countries) need no authentication at all.

Base URL: https://api.numberotp.com/v1 or https://numberotp.com/v1 — both work identically, the api. subdomain just skips the marketing site.

2Public Endpoints (No Auth)

GET/v1/public/services

List all available services (WhatsApp, Telegram, etc). Optional ?country= to filter.

Auth: NoneRate limit: 100 / 60s per IP
GET/v1/public/countries

List all available countries. Optional ?service= to only show countries supporting a specific service.

Auth: NoneRate limit: 100 / 60s per IP
GET/v1/public/prices

Real-time pricing and availability for all services and countries. Optional ?service= and ?country= filters. Cached ~5 minutes.

Auth: NoneRate limit: 100 / 60s per IP

3Activations & Rentals

POST/v1/activations

Provision a virtual phone number for SMS reception. Body: { service, country, pool?, max_price? } — pool 'auto' (default) picks the pool with the best measured delivery rate and switches automatically if it can't supply a number; max_price caps what you'll pay. Returns the phone number and activation id. Balance is deducted instantly.

Auth: Bearer API keyRate limit: 60 / 60s per user
GET/v1/activations/{id}

Poll the status of an activation and its OTP, once received.

Auth: Bearer API keyRate limit: No limit currently
GET/v1/activations/{id}/wait

Long-polling — this connection hangs open (up to 55s) and returns the instant the OTP arrives, instead of you polling in a loop.

Auth: Bearer API keyRate limit: No limit currently
POST/v1/rentals

Rent a number for longer-term use (hours/days) rather than a single OTP.

Auth: Bearer API keyRate limit: 60 / 60s per user

Every response includes X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers where a limit applies. A 429 means you've hit it.

4Zero-Latency Webhooks

For the fastest possible OTP delivery, set a Global Webhook. When an SMS arrives for your active number, it's POSTed to your URL instantly — no polling needed.

Setup

Set your webhook URL and secret in Developer → Global Webhook.

Payload

{
  "id": "act_8f7d98x",
  "phone_number": "14155552671",
  "service": "wa",
  "country": "67",
  "otp": "482910",
  "full_sms": "Your WhatsApp code is 482910.",
  "status": "received"
}

Signature verification (HMAC-SHA256)

Every request includes a signature over the raw JSON body, keyed with your webhook secret:

x-numberotp-signature: sha256=10f4be...
const crypto = require('crypto');

function verifyWebhook(reqBody, signatureHeader, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(reqBody))
    .digest('hex');

  const expectedSignature = `sha256=${hash}`;

  return crypto.timingSafeEqual(
    Buffer.from(signatureHeader),
    Buffer.from(expectedSignature)
  );
}