SMSReactor
REST · JSON · developers

API documentation

Use SMSReactor from your own backend: authenticate with an API key, queue SMS with JSON, and let the Android app on your SIM deliver them — anywhere that phone can send. The same key also pairs the phone. Free accounts get 30 SMS credits per day.

https://smsreactor.com/smsapi/

Quick start for developers

Your software talks to SMSReactor. A phone running the SMSReactor app is the radio that actually sends. Keep that app online.

  1. Create a free account and sign in to the dashboard.
  2. Open API keys, create a key, scan the QR with the Android app, tap Start gateway.
  3. From your server, POST /smsapi/create-task with header X-API-Key.
  4. Your connected phone sends the SMS (wherever that SIM can reach). Replies show up in the dashboard inbox.
Application integrations use only the API key. Do not send X-Worker-Token from your product — that header is for the phone app / operator path.

Authentication

Client endpoints require an API key in the request header (or, for quick tests, as a query parameter).

Header
X-API-Key: skr_your_key_here

Alternative (less preferred):

Query
?api_key=skr_your_key_here
Keys are created under Dashboard → API keys (clients) or Clients → Manage (admin). The raw key is shown once at creation.

Send SMS

POST /smsapi/create-task

Queues one SMS. Costs 1 credit. Your connected Android app phone delivers it — local or international, whatever that SIM / carrier allows. The gateway app must stay running.

There is no rented gateway number and no shared operator fallback. If you have no active own-app phone, the API returns HTTP 400 with No app phone registered…

Request body

FieldTypeRequiredDescription
recipient string yes Destination number. Prefer E.164 with a country code (e.g. +381611234567, +491761234567, +15551234567). Local 06x… is accepted and stored as +381…. Reach is whatever your connected SIM can send — we do not restrict country.
message string yes SMS body text.
phone_id integer no Specific connected app phone. Invalid IDs are ignored. Omit (or pass an unusable ID) to use your first active own-app phone.
scheduled_at string no Local datetime YYYY-MM-DD HH:MM:SS (or YYYY-MM-DDTHH:MM). Omit for ASAP.
Request JSON
{
  "recipient": "+381611234567",
  "message": "Hello from SMSReactor!",
  "scheduled_at": "2026-07-26 18:30:00"
}

Success response

HTTP 201 Created

Response JSON
{
  "ok": true,
  "id": 42,
  "status": "pending",
  "phone_id": 1,
  "client_id": 3,
  "charged": true,
  "scheduled_at": "2026-07-26 18:30:00",
  "credits_remaining": 99
}

Credits & plans

  • Each SMS from your connected phone debits 1 credit.
  • Daily credits refill every 24 hours. Unused daily credits do not stack. Admin bonus credits persist.
  • The success body includes charged and credits_remaining. There is no separate balance endpoint.
  • Insufficient balance returns HTTP 402. Failed sends are refunded once.
PlanSMS / dayOwn phonesEUR / mo
Free 30 2 0
Starter 1,000 2 4
Basic 2,500 3 6
Standard 5,000 5 9
Pro 10,000 10 19
Business 30,000 20 39
Enterprise 50,000+ 50 79+

Errors

Errors are JSON objects with an error string (and sometimes detail).

HTTPWhen
400Missing/invalid fields, unusable recipient, or no active own-app phone registered.
401Missing, invalid, or revoked API key / worker token.
403Phone disabled, or over the plan’s phone limit on register.
402Daily credit limit reached (or no credits left).
405Wrong HTTP method.
500Unexpected server error.
503Worker path: no active gateway configured.
Example
{
  "error": "Daily send limit reached. Credits refill every 24 hours, or add bonus credits on the account."
}

Examples

cURL

bash / Windows curl
curl -X POST https://smsreactor.com/smsapi/create-task \
  -H "Content-Type: application/json" \
  -H "X-API-Key: skr_your_key_here" \
  -d '{
    "recipient": "+381611234567",
    "message": "Hello from SMSReactor!"
  }'

JavaScript (fetch)

javascript
const res = await fetch("https://smsreactor.com/smsapi/create-task", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": "skr_your_key_here",
  },
  body: JSON.stringify({
    recipient: "+381611234567",
    message: "Hello from SMSReactor!",
  }),
});
const data = await res.json();
console.log(res.status, data);

Python

python
import json, urllib.request

req = urllib.request.Request(
    "https://smsreactor.com/smsapi/create-task",
    data=json.dumps({
        "recipient": "+491761234567",
        "message": "Hello from SMSReactor!",
    }).encode(),
    headers={
        "Content-Type": "application/json",
        "X-API-Key": "skr_your_key_here",
    },
    method="POST",
)
with urllib.request.urlopen(req) as res:
    print(res.status, res.read().decode())

PHP

php
$ch = curl_init("https://smsreactor.com/smsapi/create-task");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: skr_your_key_here",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "recipient" => "+381611234567",
        "message" => "Hello from SMSReactor!",
    ]),
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $code, "\n", $body;