v1REST · JSON

SNSOTP OTP API

A REST API for SMS verification. Order a number for one of 182 services in one of 154 countries, read the one-time code from the order, and get the full price back when no code arrives in 20 minutes.

Every endpoint accepts parameters as query parameters (GET) or as form fields or JSON (POST). Answers are JSON; money is a USD string with two decimals and times are ISO 8601 in UTC.

Server

https://snsotp.com/api/v1

AuthenticationBearer token

Your API key from the console, sent as Authorization: Bearer sok_...

Authentication

Create a key on the API page of the console. It starts with sok_ and is shown once, so store it in an environment variable. Replacing the key stops the old one at once. Calls to /services, /countries and /prices work without a key.

Header
Authorization: Bearer sok_your_key_here

The key can also be sent as a key query parameter or form field, which helps tools that cannot set headers.

Quick start

Order a number, give it to the app, then poll the order until the code is there. The same flow in four languages:

# 1. Order a number for whatsapp in US
curl -X POST https://snsotp.com/api/v1/orders \
  -H "Authorization: Bearer $SNSOTP_KEY" \
  -d service=whatsapp -d country=us

# 2. Read the code (poll every 3 to 5 seconds)
curl https://snsotp.com/api/v1/orders/OT-7K2M9QX4PB \
  -H "Authorization: Bearer $SNSOTP_KEY"

GET/services

Every service with its code and lowest price · no key

Every service you can order, with its code (use it as service in other calls), its category and the lowest price across countries. No key needed.

RequestcURL
curl https://snsotp.com/api/v1/services
Response200
{
  "services": [
    { "code": "whatsapp", "name": "WhatsApp", "category": "social", "from": "0.09" },
    { "code": "telegram", "name": "Telegram", "category": "social", "from": "0.03" }
  ]
}

GET/countries

Every country with its code and dial code · no key

Every country with its code (ISO 3166 alpha-2 in lower case, use it as country) and its dial code. No key needed.

RequestcURL
curl https://snsotp.com/api/v1/countries
Response200
{
  "countries": [
    { "code": "us", "name": "United States", "dial_code": "1" },
    { "code": "gb", "name": "United Kingdom", "dial_code": "44" }
  ]
}

GET/prices

Prices for a service, a country or both · no key

The price per order for one service in every country, one country for every service, or one pair. Send at least one filter. No key needed.

Parameters

  • servicestring

    Service code, for example whatsapp

  • countrystring

    Country code, for example us

RequestcURL
curl "https://snsotp.com/api/v1/prices?service=whatsapp&country=us"
Response200
{
  "prices": [
    { "service": "whatsapp", "country": "us", "price": "0.93" }
  ]
}

GET/balance

Your credit in USD · key required

Your credit in USD.

RequestcURL
curl https://snsotp.com/api/v1/balance \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "balance": "42.50",
  "currency": "USD"
}

POST/orders

Order a number for a service and a country · key required

Orders a number and charges its price. The answer has the number in full (phone) and without the dial code (number). The order stays open for 20 minutes; with no code in that time the price returns to your credit by itself. Answer status 201.

Parameters

  • servicestringrequired

    Service code from GET /services

  • countrystringrequired

    Country code from GET /countries

RequestcURL
curl -X POST https://snsotp.com/api/v1/orders \
  -H "Authorization: Bearer $SNSOTP_KEY" \
  -d service=whatsapp -d country=us
Response201
{
  "order": {
    "id": "OT-7K2M9QX4PB",
    "service": "whatsapp",
    "country": "us",
    "phone": "+13475550182",
    "number": "3475550182",
    "dial_code": "1",
    "price": "0.93",
    "status": "waiting",
    "code": null,
    "sms": null,
    "codes": [],
    "expires_at": "2026-11-03T12:20:00.000Z"
  },
  "window_minutes": 20
}

GET/orders/{id}

Status, code and SMS text of one order · key required

One order with its status, the latest code, the latest SMS text and every code received so far. Poll every 3 to 5 seconds while the status is waiting.

Parameters

  • idpathrequired

    Order id from POST /orders

RequestcURL
curl https://snsotp.com/api/v1/orders/OT-7K2M9QX4PB \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "order": {
    "id": "OT-7K2M9QX4PB",
    "service": "whatsapp",
    "country": "us",
    "phone": "+13475550182",
    "number": "3475550182",
    "price": "0.93",
    "status": "received",
    "code": "284913",
    "sms": "Your WhatsApp code is 284913",
    "expires_at": "2026-11-03T12:20:00.000Z"
  }
}

GET/orders

Your open orders (or all with status=all) · key required

Your open orders, newest first. Add status=all for recent orders in every status.

Parameters

  • statusstring

    open (default) or all

  • limitnumber

    1 to 100, default 50

RequestcURL
curl "https://snsotp.com/api/v1/orders?status=open" \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "orders": [
    { "id": "OT-7K2M9QX4PB", "service": "whatsapp", "status": "received", "code": "284913" }
  ]
}

POST/orders/{id}/resend

Another code on the same number · key required

Asks for another code on the same number after the first code, inside the window, at no extra cost. Then trigger a new SMS in the app; waiting_for_resend is true until it arrives.

Parameters

  • idpathrequired

    Order id

RequestcURL
curl -X POST https://snsotp.com/api/v1/orders/OT-7K2M9QX4PB/resend \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "order": { "id": "OT-7K2M9QX4PB", "status": "received", "waiting_for_resend": true }
}

POST/orders/{id}/finish

Close an order after you used the code · key required

Closes an order that received a code once you have used it. Finishing is optional: open orders close by themselves when the window ends.

Parameters

  • idpathrequired

    Order id

RequestcURL
curl -X POST https://snsotp.com/api/v1/orders/OT-7K2M9QX4PB/finish \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "order": { "id": "OT-7K2M9QX4PB", "status": "finished" }
}

POST/orders/{id}/cancel

Cancel before a code, full refund · key required

Cancels an order before a code arrives and returns the full price to your credit at once. After a code, cancel answers has_code.

Parameters

  • idpathrequired

    Order id

RequestcURL
curl -X POST https://snsotp.com/api/v1/orders/OT-7K2M9QX4PB/cancel \
  -H "Authorization: Bearer $SNSOTP_KEY"
Response200
{
  "order": { "id": "OT-7K2M9QX4PB", "status": "canceled", "refunded": "0.93" }
}

Order status

status values
  • waitingThe number is ready and no SMS has arrived yet. Cancel is possible.
  • receivedAt least one code arrived. code and sms hold the latest one.
  • finishedClosed after a code, by finish or when the window ended.
  • refundedNo code arrived in 20 minutes. The full price is back in your credit.
  • canceledCanceled before a code. The full price is back in your credit.

Errors

Errors use the HTTP status and a body with a stable code and a readable message.

HTTP status and codes
  • 400missing_filter, bad_jsonA required value is missing or the body cannot be read.
  • 401no_key, bad_keyThe key is missing, wrong or deleted.
  • 402no_balanceNot enough credit for this order. Add credit in the console.
  • 404unknown_service, unknown_country, not_sold, not_foundThe code or the order does not exist, or the pair is not sold.
  • 409too_many_open, has_code, not_ready, no_numbersThe action does not fit the order state, or no number is free right now (nothing is charged).
  • 429rate_limitedMore than 300 requests in a minute with one key.
Error body402
{
  "error": {
    "code": "no_balance",
    "message": "Not enough credit. Add credit in the console."
  }
}

Rate limits

  • 300 requests per minute per key. Above that the API answers 429 rate_limited for the rest of the minute.
  • Up to 20 open orders per account. Finish or cancel one to open another.
  • Poll an order every 3 to 5 seconds; codes usually arrive within a minute.

SMS activation format

Scripts written for the common handler_api.php format work with the same API key: change the base address to https://snsotp.com/stubs/handler_api.php and keep the actions. Service and country codes are the same as in the REST API.

Actions
  • getBalance

    ACCESS_BALANCE:42.50

  • getServicesList

    JSON list of services

  • getCountries

    JSON map of countries

  • getPricesservice, country (optional)

    JSON {country: {service: {cost, count}}}

  • getNumberservice, country

    ACCESS_NUMBER:<id>:<phone>

  • getStatusid

    STATUS_WAIT_CODE, STATUS_OK:<code>, STATUS_WAIT_RETRY:<code>, STATUS_CANCEL

  • setStatusid, status 1 / 3 / 6 / 8

    ACCESS_READY, ACCESS_RETRY_GET, ACCESS_ACTIVATION, ACCESS_CANCEL

RequestcURL
curl "https://snsotp.com/stubs/handler_api.php\
?api_key=$SNSOTP_KEY&action=getNumber\
&service=telegram&country=gb"

ACCESS_NUMBER:OT-3QF8ZK2W7M:447700900182

setStatus values: 1 ready, 3 another code, 6 finish, 8 cancel with a full refund.

OTP API Documentation: SMS Verification REST API | SNSOTP