REST API · v1
Numariq API Reference
Buy real, non-VoIP US verification numbers and read incoming codes programmatically — the same flow the web app uses. Everything is plain JSON over HTTPS, and all amounts are integer cents (e.g. 10 = $0.10).
- Base URL
https://numariq.com/api/v1- Format
- JSON request & response bodies (UTF-8)
- Auth
- API key (header) — see below
- Money
- Integer cents (USD)
Quickstart — a WhatsApp code in 4 calls
- Find the service.
GET /services?country=US&channel=sms→ note theslugfor WhatsApp. - Buy a number.
POST /numberswith{"country":"US","service":"whatsapp"}→ returns anorder.idand thenumber. - Poll for the code.
GET /orders/:idevery few seconds untilcodeis non-null. - Finish.
POST /orders/:id/doneonce you have used it — orPOST /orders/:id/cancelto get an automatic refund if no code arrived.
export NUMARIQ_KEY=nmq_xxxxxxxx
# 1. buy
ORDER=$(curl -s -X POST "https://numariq-next.vercel.app/api/v1/numbers" \
-H "X-API-Key: $NUMARIQ_KEY" -H "content-type: application/json" \
-d '{"country":"US","service":"whatsapp"}' | jq -r .order.id)
# 2. poll until a code shows up
curl -s "https://numariq-next.vercel.app/api/v1/orders/$ORDER" -H "X-API-Key: $NUMARIQ_KEY" | jq .code
# 3. release
curl -s -X POST "https://numariq-next.vercel.app/api/v1/orders/$ORDER/done" -H "X-API-Key: $NUMARIQ_KEY"Authentication
Generate an API key on your account page. The key is shown once at creation (we only store its hash) — copy it then. You can regenerate at any time, which invalidates the old key. Keys look like nmq_….
Send it on every request, either as a dedicated header or as a bearer token:
X-API-Key: YOUR_KEY
# …or…
Authorization: Bearer YOUR_KEYA missing key returns 401; an unrecognised key returns 401 with {"error":"Invalid API key."}. Treat your key like a password and never ship it in client-side code.
Order lifecycle
Every purchase is an order. The status field walks through:
waiting— number reserved, no code yet. Activations auto-expire after 15 minutes (and are refunded).received— at least one SMS/code has arrived.done— you confirmed completion (/done) or a rental period finished.expired— timed out before a code arrived (activations are auto-refunded).cancelled— you cancelled; refunded if no code had arrived.
Endpoints
/servicesList enabled services and their per-activation price for a country/channel.
| Param | In | Required | Description |
|---|---|---|---|
country | query | no | ISO country code. Default US. |
channel | query | no | sms or voice. Default sms. |
cURL
curl "https://numariq-next.vercel.app/api/v1/services?country=US&channel=sms" \
-H "X-API-Key: $NUMARIQ_KEY"JavaScript (fetch)
const r = await fetch(
"https://numariq-next.vercel.app/api/v1/services?country=US&channel=sms",
{ headers: { "X-API-Key": process.env.NUMARIQ_KEY } }
);
const { services } = await r.json();Response · 200 OK
{
"country": "US",
"channel": "sms",
"services": [
{ "slug": "google", "name": "Google", "channel": "sms", "price_cents": 10 },
{ "slug": "whatsapp", "name": "WhatsApp", "channel": "sms", "price_cents": 20 }
]
}/numbersBuy a number. Charges your balance and reserves a number, returning the new order. Use type=activation for a one-time code, type=rental to hold a number.
| Param | In | Required | Description |
|---|---|---|---|
country | body | yes | ISO country code — currently US only. |
type | body | no | "activation" (default) or "rental". |
service | body | activation | Service slug, e.g. whatsapp. Required for activations. |
channel | body | no | "sms" (default) or "voice". |
area_code | body | no | Preferred US area code, e.g. 212. |
period_days | body | rental | Rental tier: 7 ($29), 30 ($49), or 90 ($129). Default 30. The number auto-renews each period — turn renewable:false to let it lapse. |
renewable | body | rental | Auto-renew to keep the number. Default true for rentals; set false for a one-off period. |
cURL
# activation
curl -X POST "https://numariq-next.vercel.app/api/v1/numbers" \
-H "X-API-Key: $NUMARIQ_KEY" -H "content-type: application/json" \
-d '{"country":"US","service":"whatsapp","channel":"sms","area_code":"212"}'
# 30-day rental ($49, auto-renews — the default tier)
curl -X POST "https://numariq-next.vercel.app/api/v1/numbers" \
-H "X-API-Key: $NUMARIQ_KEY" -H "content-type: application/json" \
-d '{"country":"US","type":"rental","period_days":30}'
# 7-day rental ($29), no auto-renew
curl -X POST "https://numariq-next.vercel.app/api/v1/numbers" \
-H "X-API-Key: $NUMARIQ_KEY" -H "content-type: application/json" \
-d '{"country":"US","type":"rental","period_days":7,"renewable":false}'JavaScript (fetch)
const r = await fetch("https://numariq-next.vercel.app/api/v1/numbers", {
method: "POST",
headers: {
"X-API-Key": process.env.NUMARIQ_KEY,
"content-type": "application/json",
},
body: JSON.stringify({ country: "US", service: "whatsapp" }),
});
const { order } = await r.json();
// order.id, order.number, order.status === "waiting"Response · 201 Created
{
"order": {
"id": "5f3c…-order-uuid",
"status": "waiting",
"type": "activation",
"channel": "sms",
"price_cents": 20,
"number": "+12125550199",
"expires_at": "2026-06-07T18:15:00Z",
"renews_at": null
}
}Common failures (400): insufficient balance, no numbers available for this selection, unknown or disabled service, rental days must be 1-14.
/orders/:idFetch an order's status, the assigned number, and any code received. Poll this until code is non-null.
| Param | In | Required | Description |
|---|---|---|---|
id | path | yes | The order id returned by POST /numbers. |
cURL
curl "https://numariq-next.vercel.app/api/v1/orders/ORDER_ID" -H "X-API-Key: $NUMARIQ_KEY"JavaScript (fetch)
const r = await fetch("https://numariq-next.vercel.app/api/v1/orders/" + orderId, {
headers: { "X-API-Key": process.env.NUMARIQ_KEY },
});
const { order, code, messages } = await r.json();
if (code) { /* verified */ }Response · 200 OK
{
"order": {
"id": "5f3c…-order-uuid",
"status": "received",
"type": "activation",
"channel": "sms",
"service": "whatsapp",
"number": "+12125550199",
"price_cents": 20,
"expires_at": "2026-06-07T18:15:00Z",
"renews_at": null
},
"code": "558213",
"messages": [
{
"id": "msg-uuid",
"sender": "WhatsApp",
"body": "Your code is 558-213",
"code": "558213",
"received_at": "2026-06-07T18:03:11Z"
}
]
}Returns 404 with {"error":"Order not found."} if the id is unknown or owned by another account. code is null until a recognisable code arrives.
/orders/:id/doneMark an activation complete once you have used the code. Finalises the order.
| Param | In | Required | Description |
|---|---|---|---|
id | path | yes | The order id. |
cURL
curl -X POST "https://numariq-next.vercel.app/api/v1/orders/ORDER_ID/done" -H "X-API-Key: $NUMARIQ_KEY"JavaScript (fetch)
await fetch("https://numariq-next.vercel.app/api/v1/orders/" + orderId + "/done", {
method: "POST",
headers: { "X-API-Key": process.env.NUMARIQ_KEY },
});Response · 200 OK
{ "ok": true, "status": "done" }/orders/:id/cancelCancel an activation. Automatically refunds your balance if no code had arrived yet.
| Param | In | Required | Description |
|---|---|---|---|
id | path | yes | The order id. |
cURL
curl -X POST "https://numariq-next.vercel.app/api/v1/orders/ORDER_ID/cancel" -H "X-API-Key: $NUMARIQ_KEY"JavaScript (fetch)
const r = await fetch("https://numariq-next.vercel.app/api/v1/orders/" + orderId + "/cancel", {
method: "POST",
headers: { "X-API-Key": process.env.NUMARIQ_KEY },
});
const { result } = await r.json(); // "refunded" | "closed"Response · 200 OK
{ "ok": true, "result": "refunded" }result is "refunded" when no code had arrived, or "closed" when a code was already delivered (no refund).
/rentals/:id/renewCharge and extend a renewable rental immediately, instead of waiting for the automatic renewal.
| Param | In | Required | Description |
|---|---|---|---|
id | path | yes | The rental order id (must be a renewable rental). |
cURL
curl -X POST "https://numariq-next.vercel.app/api/v1/rentals/ORDER_ID/renew" -H "X-API-Key: $NUMARIQ_KEY"JavaScript (fetch)
await fetch("https://numariq-next.vercel.app/api/v1/rentals/" + orderId + "/renew", {
method: "POST",
headers: { "X-API-Key": process.env.NUMARIQ_KEY },
});Response · 200 OK
{ "ok": true, "status": "renewed" }Errors
Errors use standard HTTP status codes and a single-field JSON body:
{ "error": "human-readable message" }| Status | Meaning |
|---|---|
400 | Bad request — invalid params, insufficient balance, or no numbers available. |
401 | Missing or invalid API key. |
404 | Order not found (or not owned by your account). |
503 | API temporarily not configured on the server. |
Rate limits & best practices
- Poll politely. When waiting for a code, poll
GET /orders/:idevery 3–5 seconds. Activations expire after 15 minutes — there is no benefit to polling faster. - Always release orders. Call
/donewhen you have the code, or/cancelif it never arrives, so unused activations are refunded promptly. - Check the service first. Use
GET /servicesfor valid slugs and live prices rather than hard-coding them. - Handle 400s gracefully.
no numbers availableis transient — back off and retry, or pick another service/area code. - Keep your key server-side. Each key is tied to one account and its balance.
There are currently no fixed per-minute request quotas, but abusive traffic may be throttled. Build with reasonable retry/back-off so your integration stays well-behaved.