API docs

Create orders, receive codes and renew numbers from your server. All amounts are integer micro-USD: $1 = 1,000,000.

Authentication and retries

Create an API key in the console and pass Authorization: Bearer obk_…. Retry order creation with the same Idempotency-Key. Do not change the key after a network error. Uncertain rental renewals remain pending reconciliation; do not resubmit.

Endpoints · /api/v1

HTTPPathPurpose
GET/balanceWallet balance
GET/services?country=US&q=telegramServices and prices
GET/prices?kind=rental&country=US&service=whatsappRental prices
POST/verificationsCreate verification
GET/verificationsList verifications
GET/verifications/:idRead order and messages
POST/verifications/:id/cancelCancel
POST/verifications/:id/reportReport wrong code
POST/rentalsCreate rental
GET/rentalsList rentals
GET/rentals/:idRead rental
GET/rentals/:id/messagesRental messages
POST/rentals/:id/extendExtend
POST/rentals/:id/refundRequest eligible refund
PATCH/rentals/:idUpdate autoRenew
GET/transactionsWallet ledger
GET/verifications/:id/shareSharing status
POST/verifications/:id/shareCreate or replace sharing token
DELETE/verifications/:id/shareRevoke sharing token
GET/rentals/:id/shareSharing status
POST/rentals/:id/shareCreate or replace sharing token
DELETE/rentals/:id/shareRevoke sharing token

Rental body: { country, days, autoRenew }. Rentals require Idempotency-Key. Order responses are wrapped in verification or rental.

Examples

curl

curl -X POST https://YOUR_DOMAIN/api/v1/verifications   -H 'Authorization: Bearer obk_PREFIX_SECRET'   -H 'Idempotency-Key: my-order-0001'   -H 'Content-Type: application/json'   -d '{"service":"whatsapp","country":"US"}'

JavaScript

// Keep this key when retrying this order.
const orderKey = crypto.randomUUID();
const response = await fetch(baseUrl + '/api/v1/verifications', {
  method: 'POST',
  headers: { Authorization: 'Bearer ' + apiKey, 'Content-Type': 'application/json',
    'Idempotency-Key': orderKey },
  body: JSON.stringify({ service: 'whatsapp', country: 'US' })
});
const result = await response.json();
if (!response.ok) throw new Error(result.error?.code);

Python

import requests, uuid
# Keep this key when retrying this order.
order_key = str(uuid.uuid4())
r = requests.post(base_url + '/api/v1/verifications',
  headers={'Authorization': 'Bearer ' + api_key, 'Idempotency-Key': order_key},
  json={'service': 'whatsapp', 'country': 'US'})
r.raise_for_status()
print(r.json())

Read codes without signing in

An order sharing token lets you read its number, current status and messages without a web login, cookie or OneBox account key. Use the Bearer token below, or POST JSON { token }. Sharing links have no automatic expiry and can be revoked or replaced by the owner. The rental keeps its purchased end date.

curl https://YOUR_DOMAIN/api/auth/order-share/read \
  -H 'Authorization: Bearer ORDER_SHARE_TOKEN'

Returns { order: { kind, service, country, phone, status, latestCode, latestMessageAt, endsAt, linkExpiresAt, messages } }. Invalid or revoked tokens return 404. Manage sharing tokens through /api/v1/.../share above, without a web login.

Errors

Errors use { error: { code, message } }. Handle the HTTP status and stable code.

401 unauthorized
402 insufficient_balance
403 email_not_verified / service_prohibited / account_suspended
404 not_found
409 out_of_stock / renewal_pending / not_renewable
429 rate_limited / order_limit
503 upstream_unavailable / payment_provider_not_configured

Webhook

Subscribe to verification.received, verification.expired, rental.message and rental.expiring. Verify the timestamp and HMAC-SHA256 in X-OneBox-Signature, deduplicate the event id and return 2xx. Failures retry after 1, 5, 30 minutes, 2 and 6 hours, then disable the endpoint.

import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody must be the exact received bytes, before JSON parsing.
const parts = Object.fromEntries(signatureHeader.split(',').map(p => p.split('=')));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) throw new Error('expired');
const expected = createHmac('sha256', secret).update(parts.t + '.' + rawBody).digest();
const provided = Buffer.from(parts.v1 || '', 'hex');
if (expected.length !== provided.length || !timingSafeEqual(expected, provided))
  throw new Error('invalid signature');
// Deduplicate payload.id, then return HTTP 2xx.

Service-specific rentals

Read prices for the selected service before ordering. maxPrice is an integer in micro-USD; a higher price rejects the purchase. Omitting service selects All Services.

curl -X POST https://YOUR_DOMAIN/api/v1/rentals \
  -H 'Authorization: Bearer obk_PREFIX_SECRET' \
  -H 'Idempotency-Key: rental-whatsapp-30d-0001' \
  -H 'Content-Type: application/json' \
  -d '{"service":"whatsapp","country":"US","days":30,"autoRenew":false,"maxPrice":7200000}'