Receive SMS verification codes with Node.js
Quick answer
Node 18+ has fetch built in, so you can call the Noir SMS API without dependencies. Send POST /api/v1/numbers with service and country and a Bearer key, then poll GET /api/v1/numbers/{id} until status is received and read sms[0].code. Errors come back with a stable error.code like insufficient_balance or no_numbers that you can switch on.
Here's a small, dependency-free helper you can drop into a script, a worker or a backend route.
Requirements
- Node.js 18 or newer (for global fetch and top-level await in .mjs files).
- An API key from the API page in your dashboard, in NOIRSMS_KEY.
The code
const API = 'https://noirsms.com/api/v1';
const H = { Authorization: `Bearer ${process.env.NOIRSMS_KEY}`, 'Content-Type': 'application/json' };
async function call(path, opts = {}) {
const r = await fetch(API + path, { headers: H, ...opts });
const body = await r.json();
if (!r.ok) throw Object.assign(new Error(body.error?.message), { code: body.error?.code, status: r.status });
return body;
}
const buy = (service, country) =>
call('/numbers', { method: 'POST', body: JSON.stringify({ service, country }) });
async function waitForCode(id) {
for (;;) {
const n = await call(`/numbers/${id}`);
if (n.status === 'received') return n.sms[0].code;
if (n.status === 'canceled' || n.status === 'expired') return null;
await new Promise((r) => setTimeout(r, 4000));
}
}
const n = await buy('wa', 'gb');
console.log('Number:', n.phone);
console.log('Code:', await waitForCode(n.id));In production
- Prefer the sms.received webhook over polling for many numbers at once.
- Verify the X-NoirSMS-Signature header on every webhook.
- Log the number id with each order so you can cancel or finish it later.
Use it responsibly
Use the API only for your own legitimate accounts or apps you're authorized to test, and make sure your customers follow the same Acceptable Use Policy.
Frequently asked questions
Does it work in Cloudflare Workers or Deno?
Yes. The example only uses fetch, which those runtimes provide.
What country codes are used?
2-letter ISO codes in lowercase, such as us, gb and ca.
Services in this guide
Keep reading
Receive SMS verification codes with Python
Buy a temporary number and read the SMS verification code from Python with the Noir SMS REST API. Full example with requests, polling and errors.
Read the guide →DevelopersReceive SMS verification codes with PHP
Use PHP and cURL to buy a temporary number and read the SMS verification code with the Noir SMS API. Copy-paste example for panels and scripts.
Read the guide →DevelopersCommon Noir SMS API errors and how to handle them
Every Noir SMS API error code explained: invalid_api_key, insufficient_balance, no_numbers, too_early, rate_limited and more, with a retry pattern.
Read the guide →DevelopersUsing virtual numbers to test SMS flows
How QA teams use real virtual numbers to test SMS sign-up and OTP flows end to end, when to use them vs test numbers, and how to automate with an API.
Read the guide →DevelopersTesting OTP and SMS sign-up flows in staging
Run end-to-end tests of your app's SMS sign-up in staging with real temporary numbers: Playwright example, what to check and how to keep costs low.
Read the guide →DevelopersAutomate receiving SMS codes: polling or webhooks
Two ways to receive SMS verification codes automatically with the Noir SMS API: polling GET /numbers/{id} or a signed sms.received webhook. Code included.
Read the guide →