Overview
The API does what the dashboard does. You ask for a number for one service, we rent it, and you read the verification message it receives. Every request is JSON over HTTPS and every response is JSON.
https://smstogo.net/api/v1Numbers are available in the United States today. The catalog endpoint always tells you exactly what can be ordered right now, so read it rather than hard-coding a service list.
There is no published rate limit. A pending order is refreshed against our upstream provider at most once every 15 seconds, so polling faster than that returns the last state we know rather than a newer one.
Authentication
Every request carries your API key as a bearer token. Generate one under Settings in your dashboard. The key is shown once, at the moment it is created: we store only a hash of it, so nobody — including us — can read it back afterwards.
curl https://smstogo.net/api/v1/account/balance \
-H "Authorization: Bearer sk_9fA2kQzB…"A key spends your balance, so treat it like a password: keep it server-side, out of version control, and out of anything that runs in a browser. Generating a new key retires the old one immediately — that is how you revoke one that leaked.
A missing, unknown, or retired key returns 401. Session cookies are not accepted here, and your key does not open the dashboard.
Balance and pricing
Orders are charged to the balance of the account the key belongs to — the same balance your dashboard shows, topped up the same way. There is no separate API billing.
All money is expressed in integer minor units of the currency: price_minor of 50 in USD is $0.50. Never parse a decimal; the integer is the source of truth.
You are charged when the order is created, before we ask the provider for a number. An order that never delivers a message — cancelled, expired, or never rented — is refunded in full, automatically. A delivered order is final.
GET/account/balance
The balance every order on this key is charged against.
{
"currency": "USD",
"balance_minor": 2500
}Catalog
What you can actually order, with the price you will be charged. This is narrower than the catalog on our marketing pages, and it is the list to order from.
GET/services
Every country and service pair open for ordering.
[
{
"country_code": "us",
"service_slug": "google",
"service_name": "Google",
"price_minor": 50,
"currency": "USD"
}
]Orders
An order is one rented number for one service. Create it, poll it until a code arrives, and cancel it if you no longer need it.
POST/orders
Charge your balance and rent a number. Responds 201 with the order.
- country_codestring
- Country of the number, as given by the catalog — for example "us".
- service_slugstring
- Service the number is for, as given by the catalog — for example "google".
{
"id": "6f1b0c2a-8d54-4f0a-9a1e-2c0b7d3e51aa",
"status": "waiting_sms",
"country_code": "us",
"service_slug": "google",
"service_name": "Google",
"phone_number": "15302286946",
"carrier": "TMobile",
"price_minor": 50,
"currency": "USD",
"failure_reason": null,
"expires_at": "2026-09-11T18:22:04Z",
"completed_at": null,
"refunded_at": null,
"created_at": "2026-09-11T18:07:04Z",
"messages": []
}GET/orders/{order_id}
Read one order and any message it has received. This is the endpoint to poll.
{
"id": "6f1b0c2a-8d54-4f0a-9a1e-2c0b7d3e51aa",
"status": "completed",
"phone_number": "15302286946",
"completed_at": "2026-09-11T18:09:31Z",
"messages": [
{
"id": "b83c1f77-1a4e-4c33-9f2d-77a0c5e9d410",
"sender": "22000",
"body": "G-804036 is your Google verification code.",
"code": "G-804036",
"received_at": "2026-09-11T18:09:28Z"
}
]
}The verification code is on each message as code, with the full text in body. A message is stored once, so the same code never appears twice.
GET/orders
Your 20 most recent orders, newest first.
POST/orders/{order_id}/cancel
Give a number back before its code arrives and refund the charge in full.
Cancelling an order that already received a message is refused with 409: it delivered what you paid for.
Order status
status is how far along the order is. The first three can still change on their own; the last four are final.
- reservingpending
- Charged and recorded. The provider has not answered yet.
- awaiting_numberpending
- The request is accepted but no number has been assigned.
- waiting_smspending
- A number is reserved and phone_number is set. Poll from here.
- completedfinal
- A message arrived and is in messages. The order stays charged.
- cancelledfinal · refunded
- You gave the number back before a message arrived.
- expiredfinal · refunded
- The rental window closed without a message.
- failedfinal · refunded
- No number was ever rented. failure_reason says what happened.
Errors
Anything other than a 2xx carries a JSON body with a detail string written for a person to read. Branch on the status code, not on the wording.
{
"detail": "Your balance is too low for this number. Top up and try again."
}- 401Unauthorized
- The key is missing, unknown, retired, or its account is closed.
- 402Payment required
- Your balance is below the price of this number. Nothing was charged.
- 404Not found
- No such order on this account, or no such country and service pair.
- 409Conflict
- The pair exists but cannot be ordered, no numbers are free for it, or the order is already finished.
- 422Unprocessable content
- The request body is missing a field or malformed.
- 502 · 503Upstream unavailable
- We could not reach the number provider. Nothing was charged; retry shortly.