Buy a number, poll for the code, get on with your day. Five REST endpoints over the same wallet and inventory as the app — nothing to reconcile, no separate billing.
All requests go to https://api.foones.com/v1 and carry your key as a bearer token. Create keys in the app under Profile & settings → API keys — each key is shown in full exactly once, and you can revoke any key instantly without touching the others.
curl https://api.foones.com/v1/balance \ -H "Authorization: Bearer sk_live_your_key_here"
Keys act as your account: they spend your wallet balance. Keep them out of client-side code and public repos.
Live availability and pricing for every service, in one call.
curl https://api.foones.com/v1/services \
-H "Authorization: Bearer sk_live_…"
[
{ "id": "whatsapp", "name": "WhatsApp", "price": "3.00", "available": 4 },
{ "id": "telegram", "name": "Telegram", "price": "2.50", "available": 7 }
]Your wallet is charged and a number is allocated in the same call. If nothing is free you get 409 no_stock and pay nothing.
curl -X POST https://api.foones.com/v1/orders \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{ "service": "whatsapp" }'
{
"id": "0d9f1c2a-…",
"service": "whatsapp",
"number": "+12025550123",
"status": "active",
"codes": [],
"created_at": "2026-07-17T14:03:00Z"
}The order object is the single source of truth — poll it every few seconds until codes is non-empty.
curl https://api.foones.com/v1/orders/0d9f1c2a-… \
-H "Authorization: Bearer sk_live_…"
{
"id": "0d9f1c2a-…",
"service": "whatsapp",
"number": "+12025550123",
"status": "completed",
"codes": [
{ "code": "482913", "received_at": "2026-07-17T14:04:12Z" }
],
"created_at": "2026-07-17T14:03:00Z"
}The whole surface. Every endpoint returns JSON; POST /orders and GET /orders/{id} return the identical order object.
/v1/balanceYour current wallet balance. Top up in the app — API orders and app orders share the same wallet.
{ "balance": "12.50", "currency": "USD" }/v1/servicesEvery service with its current price and the number of SIMs available right now. available is live — checking it before ordering beats handling no_stock after.
/v1/ordersBuy a number for a service. Body: { "service": "<id>" }. Atomic: you are charged if and only if a number is allocated. Prices are computed server-side — the amount you see in /v1/services is the amount you pay.
/v1/orders/{id}The full state of an order: number, status (active → completed, or cancelled / failed) and every code received so far. Poll this until a code lands; a sensible interval is 3–5 seconds.
/v1/orders/{id}Cancel an order that hasn't received a code yet — the charge is refunded to your wallet in full. Orders that already received a code are complete and can't be cancelled.
{ "id": "0d9f1c2a-…", "status": "cancelled", "refunded": true }Errors use honest HTTP status codes and a stable machine-readable code — branch on that, not the message.
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_key | Missing, unknown, or revoked API key. |
| 402 | insufficient_balance | Wallet doesn't cover the order — top up in the app. |
| 404 | not_found | No such order on this account. |
| 409 | no_stock | No number free for that service right now. Nothing was charged; retry later or watch /v1/services. |
| 429 | rate_limited | Slow down — respect the Retry-After header. |
{ "error": { "code": "no_stock", "message": "No WhatsApp numbers available right now. Check GET /v1/services for live stock." } }Sign up, top up your wallet, create a key in Profile & settings — your first number is one POST away. Questions or higher-volume needs? Email [email protected].