Instant SMS
Read-only REST API

Developer REST API

A read-only REST API over the same public catalog the website uses: list countries, list temporary numbers, and poll inboxes for verification codes. Useful for automated testing of SMS sign-up flows. There is no self-serve sign-up - email us and we issue you a token.

This API is read-only and access is granted manually. There is no public sign-up page and no published SDK package to install - use any HTTP client with the Bearer token we issue you.

Getting Started

Four steps from zero to your first automated verification code.

1

Email us for access

Send a note from the contact page describing your use case and roughly how many requests per minute you expect. There is no public registration form.

2

Receive your Bearer token

We issue a token and send it to you once. Store it as a secret in your CI or environment file - it is not retrievable later, and a lost token has to be replaced.

3

Call the endpoints with any HTTP client

Send Authorization: Bearer {token} with every request. cURL, Guzzle, Axios, Dio, and requests all work - there is nothing to install.

4

Pick a number and poll messages

List numbers for a country, choose an active one, trigger the SMS in your app, then poll the messages endpoint until the verification code arrives. Numbers are shared and cannot be reserved.

Need an API token?

Tokens are issued by hand. Email us your use case and expected request rate and we will send one back.

Request access

Authentication & Base URL

Bearer token

Send the token we issue you in the Authorization header on every request; without it the API returns 401. Keep it server-side - never commit it or ship it in browser or mobile code, because anything shipped to a client can be extracted.

Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

Base URL

All endpoints are versioned under /api/v1. Responses are JSON with standard HTTP status codes.

https://instant-sms.com/api/v1

Response Format

One envelope for every endpoint, and a fixed pagination allow-list.

Successful responses return { "message", "data" }. Errors on 401, 403, 404, 405, and 429 return { "message", "errors" }, so you can branch on one shape. Lists are paginated with a per_page allow-list of 15, 25, or 50 - other values are rejected rather than silently clamped.

Message timestamps are ISO-8601. Numbers are identified by their E.164 digits, and the catalog only exposes public numbers - there is no reservation or ownership model, so treat every inbox as shared.

API Endpoints

Read-only endpoints for listing numbers and reading public inbox messages.

GET /api/v1/countries

List all enabled countries with number counts and activity stats. Paginated (per_page 15, 25, or 50).

GET /api/v1/countries/featured

List enabled countries flagged as featured, in the same shape as the countries list.

GET /api/v1/countries/{iso}/numbers

List public temporary numbers for a two-letter country code (e.g. us, ca, gb).

GET /api/v1/numbers/featured

List the curated featured numbers across all countries.

GET /api/v1/numbers/{number}/messages

List SMS for a number in E.164 digits. Add ?sync=1 to pull from the upstream provider first; omit it for a faster database-only read.

Example response - GET /api/v1/numbers/{number}/messages

{
  "message": "Messages retrieved.",
  "data": [
    {
      "id": 1042,
      "service": "Google",
      "body": "Your Google verification code is 847291",
      "code": "847291",
      "received_at": "2026-09-06T14:32:25+00:00"
    }
  ]
}

Code Examples

Copy a snippet and replace YOUR_API_TOKEN with the token we issued you. No SDK required.

# List US numbers
curl -s "https://instant-sms.com/api/v1/countries/us/numbers" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

# Read an inbox, pulling from the upstream provider first
curl -s "https://instant-sms.com/api/v1/numbers/14165550198/messages?sync=1" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

# Same read without the upstream pull (faster, database only)
curl -s "https://instant-sms.com/api/v1/numbers/14165550198/messages" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"
const BASE = 'https://instant-sms.com/api/v1';
const headers = {
  Authorization: `Bearer ${process.env.INSTANTSMS_API_TOKEN}`,
  Accept: 'application/json',
};

const get = async (path) => {
  const response = await fetch(`${BASE}${path}`, { headers });
  if (! response.ok) throw new Error(`${response.status} ${await response.text()}`);
  return response.json();
};

// Pick a Canadian number for your test
const { data: numbers } = await get('/countries/ca/numbers');
const number = numbers.find((n) => n.active);
console.log('Using number:', number.number);

// Trigger the SMS in your app here, then poll for the code
const digits = number.number.replace(/\D/g, '');
let code;

for (let attempt = 0; attempt < 24; attempt++) {
  const { data: messages } = await get(`/numbers/${digits}/messages?sync=1`);
  code = messages.find((m) => m.code)?.code;
  if (code) break;
  await new Promise((resolve) => setTimeout(resolve, 5000));
}

console.log('Verification code:', code);
use Illuminate\Support\Facades\Http;

$api = Http::baseUrl('https://instant-sms.com/api/v1')
    ->withToken(config('services.instantsms.token'))
    ->acceptJson()
    ->throw();

// List numbers and pick an active one
$numbers = $api->get('/countries/ca/numbers')->json('data');
$number = collect($numbers)->firstWhere('active', true);
$digits = preg_replace('/\D/', '', $number['number']);

// Trigger the SMS in your app here, then poll for the code
$code = null;

for ($attempt = 0; $attempt < 24; $attempt++) {
    $messages = $api->get("/numbers/{$digits}/messages", ['sync' => 1])->json('data');
    $code = collect($messages)->firstWhere('code', '!=', null)['code'] ?? null;

    if ($code !== null) {
        break;
    }

    sleep(5);
}

// Use $code in your Pest / PHPUnit assertion

Automated Testing Workflow

A repeatable pattern for E2E and integration tests that depend on SMS verification.

Choose a test number

Call GET /countries/{iso}/numbers and pick an active number that matches the region your app expects.

Trigger verification in your app

Enter the E.164 number in your sign-up or login flow so the service sends an SMS to the public inbox.

Poll until the code arrives

Poll GET /numbers/{slug}/messages?after={cursor} every few seconds. Stop when detected_code is present in the response.

Complete the flow

Pass the extracted code back into your app or test assertion to finish the onboarding step automatically.

Rate Limits & Guidelines

Usage limits

  • Roughly 2 requests per second and 30 per minute, keyed by token and IP.
  • Messages are retained for a limited window; poll promptly after triggering SMS.
  • Inboxes are public - never use API-fetched codes for banking, crypto, or account recovery.
  • Receive-only: numbers cannot send outbound SMS or place calls.
  • Numbers cannot be reserved. Another caller may receive a code on the same number at the same time.

Testing environments only

Public inboxes are visible to anyone. Use the API for QA, staging, and development - not for production user authentication or sensitive account recovery flows.

API - Frequently Asked Questions

Yes. Reasonable test volumes are free. Human-paced rate limits apply so one client cannot starve the upstream providers everyone shares.

Email us from the contact page with your use case and expected request rate. There is no public registration page or developer dashboard - tokens are issued by hand and sent to you once.

No. There is no published npm or Composer package. The API is plain JSON over HTTPS with a Bearer token, so any HTTP client works - cURL, Guzzle, Laravel Http, Axios, fetch, Dio, or requests.

Poll the messages endpoint with ?sync=1 so it pulls from the upstream provider before responding. Most codes arrive within 10-30 seconds; retry for up to two minutes in CI before failing the test.

No. It is built for development, QA, and staging workflows. Public temporary numbers are shared inboxes and are not suitable for verifying real users.

401 means the Bearer token is missing, malformed, or expired. 429 means you hit the rate limit - back off and retry with exponential delay rather than tightening the polling loop.

Ready to automate your SMS tests? Request an API token and start polling verification codes. Get API access.