Receive SMS Codes in Node.js: MarioSMS API Tutorial
Node 18+ ships fetch natively, so a MarioSMS integration needs zero dependencies: one call to rent a number, a polling loop to await the code, and an optional cancel. This works identically in TypeScript, plain Node scripts, and serverless functions.
You’ll need a MarioSMS account with balance and your API key from the app profile. Full endpoint reference: app.mariosms.com/api-docs. Authentication is a single X-API-Key header.
A minimal client
const BASE = 'https://app.mariosms.com/api/v1'
const KEY = process.env.MARIOSMS_API_KEY
async function api(path, { method = 'GET', body } = {}) {
const res = await fetch(`${BASE}${path}`, {
method,
headers: {
'X-API-Key': KEY,
...(body ? { 'Content-Type': 'application/json' } : {}),
},
body: body ? JSON.stringify(body) : undefined,
})
if (!res.ok) throw new Error(`MarioSMS API ${res.status}: ${await res.text()}`)
return res.json()
}
Sanity-check the key:
console.log(await api('/balance')) // { balance: 100 }
Rent a number
An activation is one number for one verification. Pick a service and country (codes from GET /services and GET /countries, live prices from GET /prices):
const activation = await api('/activation', {
method: 'POST',
body: { country: 'us', service: 'tg' }, // Telegram, US number
})
console.log(activation.phone) // "12025551234"
Await the code
Enter the number wherever you’re verifying, then poll until the status is received:
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
async function waitForCode(id, timeoutMs = 5 * 60 * 1000) {
const deadline = Date.now() + timeoutMs
while (Date.now() < deadline) {
const a = await api(`/activation/${id}`)
if (a.status === 'received') return a.smsCode // full text in a.smsText
await sleep(5000)
}
return null
}
const code = await waitForCode(activation.id)
console.log('OTP:', code)
Cancel and refund
Before an SMS arrives you can cancel for a full refund to your balance:
await api(`/activation/${activation.id}/cancel`, { method: 'POST' })
// { message: "activation cancelled", refund: 1.32 }
If your process dies mid-wait, nothing is lost: the platform auto-cancels and refunds any activation whose window expires without an SMS. You only ever pay for codes that actually arrive.
Tips
- Keep the API key in an environment variable, never in the repo.
- One activation = one code. Verifying two services means two activations.
- For CI, wrap the whole flow with your test runner’s timeout rather than relying only on the polling deadline.
- Automation is for activity you’re allowed to automate — QA, testing, legitimate account creation. See the acceptable use policy.