BusySMS

SMS gateway API

SMS gateway API for verification codes on your own numbers

The BusySMS API is the receive side of an SMS gateway. Phones you own capture the verification codes their SIMs receive, and your code asks for them with a plain HTTP request and a key. This page is the practical reference: authentication, endpoints, what comes back and what can go wrong.

$5 per verified number per month · 7-day free trial · billed by Stripe on the web

On this page

What this API does, and what it does not

Most SMS gateway APIs are built to send: you post a message and a carrier delivers it. This one is built to receive. It answers one question well, what code just arrived on my number?, for numbers on phones you have enrolled and verified.

  • Yes: read verification and one-time codes, wait for the next one, list your gateway phones and numbers, and read recently captured messages.
  • No: sending SMS, bulk or marketing campaigns, or renting and buying numbers. BusySMS supplies no numbers; you bring the SIM.

If you need to send messages, use a messaging provider. If you need the code a website texts to your number, this is the API. The phone side is covered in the Android SMS gateway guide.

Authentication

Create a key in the dashboard under REST API. It starts with bsk_live_ and is shown once, so store it as a secret, for example BUSYSMS_API_KEY. Send it on every request, in either header:

HTTP
Authorization: Bearer bsk_live_xxxxxxxx
# or
X-API-Key: bsk_live_xxxxxxxx

A key belongs to a person and only sees that person's phones, plus numbers shared with them. A key made in the dashboard can read codes, list your phones and numbers, read your account status and wake a paused phone; it cannot delete a device or manage your account, so a leaked key cannot change what you are billed. Keep keys server-side all the same: anyone holding one can read your codes.

Endpoints

Base URL https://busysms.net/api/v1. Requests are plain GETs and responses are JSON.

  • GET /codes: the newest code across your numbers. With timeoutMs it waits for the next one, up to 90 seconds. Filters: service, phone, deviceId.
  • GET /devices: your gateway phones with their id, name, number, platform, and online, verified and paused state, plus numbers shared with you.
  • GET /numbers: just your numbers, each with canReceive and, when it cannot, a reason: unverified, verification_pending, inactive, gateway_off or phone_unreachable.
  • GET /devices/:id/messages: recent captured messages for one phone, newest first. Takes service, limit (50 by default, 200 at most) and since.
  • GET /account: your account with its trial and subscription status.

Wait for a code: curl, Node.js and Python

The call most integrations need is a long-poll straight after something triggers an SMS. Start the wait, trigger the sign-in, and the request returns as soon as a matching code lands.

curl -s -H "Authorization: Bearer $BUSYSMS_API_KEY" \
  "https://busysms.net/api/v1/codes?service=exampleapp&timeoutMs=60000"

Order matters less than you might fear: a code that arrived up to about a second before the request started still counts as new, and anything older does not. In tests, start the request first and trigger the SMS second; the OTP automation guide shows how in Playwright, Selenium and Cypress.

What comes back

Every /codes response has the same shape (the message object is abridged here):

JSON
{
  "code": "482913",
  "message": {
    "otpCode": "482913",
    "phone": "+447700900123",
    "sender": "ExampleApp",
    "service": "exampleapp",
    "serviceLabel": "ExampleApp",
    "bodyPreview": "Your ExampleApp verification code is 482913",
    "receivedAt": 1792674000000,
    "deviceName": "Test phone"
  }
}

code is null when nothing new arrived in time: while waiting, the API never falls back to an older code. receivedAt is in epoch milliseconds. service is a short id BusySMS gives each message: a known brand such as google, telegram or microsoft, otherwise a slug of the sender name. Pass it as service= to wait only for that sender's code.

Errors and how to handle them

  • 401: the key is missing, malformed or revoked. A revoked key says so with key_revoked.
  • 402 payment_required: the trial ended and there is no active subscription. Reading codes stops, but /devices still answers so you can see what is wrong, and the body carries a billingUrl.
  • 403: the device belongs to another account, or the key lacks the scope for the route (insufficient_scope).
  • 404: no such device.
  • 409 number_unverified: that phone's number has not been verified yet, so its messages cannot be read.
  • 429: rate limited. Wait retryAfterMs before retrying.

Limits and good practice

  • A single wait lasts at most 90 seconds. If a code can take longer, call again with a fresh timeout instead of holding one request open.
  • With several numbers, filter: phone= with the receiving number, or deviceId= for one of your phones, so a code meant for another sign-in is not returned.
  • If none of your phones is capturing when a wait starts, BusySMS sends the phone a notification asking for the gateway to be switched back on. It never switches capture on remotely; a person taps.
  • Captured messages are kept for up to 7 days, then deleted.
  • Reading codes needs an active trial or subscription: $5 per verified number per month after a 7-day free trial. There is no per-request charge.

Beyond the REST API

The same codes are available to AI agents through the BusySMS MCP server (see SMS codes for AI agents), and to people through the Chrome extension, which fills the code into the website for you.

Numbers shared with you are included too. When a teammate shares a number's codes, /codes returns them alongside your own, and phone= picks out that number.

FAQ

Frequently asked questions

Is there a free SMS gateway API?

Every account starts with a 7-day free trial with full API access. After that it is $5 per verified phone number per month. The price is per number, not per message or per request.

Can I send SMS with this API?

No. BusySMS only receives: it reads verification codes that arrive on your own numbers. For sending, use a messaging provider.

Do I get a phone number from BusySMS?

No, BusySMS does not provide numbers. Install the app on a phone with the SIM you want and verify the number; its codes are then yours to read. An iPhone works too, through a Shortcuts automation.

Can teammates read the same number's codes?

Yes. Share the number with up to five other BusySMS users; once they accept, new codes on it reach their dashboard, apps, Chrome extension, API and MCP, at no cost to them.

Can I call the API from a browser or a mobile app?

Keep the key on a server: anyone holding it can read your codes. For a browser, use the Chrome extension, which signs in with your BusySMS account instead of a key.

Blog

More from the blog

All articles

Keep reading

Related guides

All guides

Try it on a number you own

Install the app, verify your number and read your first code today. Every account starts with a 7-day free trial; after that it is $5 per verified number per month, and you can cancel any time.