Dokumentacja API SMS do wysyłania z własnego kodu

Małe REST API na tym samym koncie, z tymi samymi cenami i saldem co obszar roboczy: wyślij wiadomość lub partię do 5,000 numerów, najpierw oszacuj koszt, śledź każdą wiadomość i otrzymuj zdarzenia dostarczenia pod swoim adresem URL webhooka.

Podstawowy URL: https://sendsmsonline.cc/api/v1

Szybki start

  1. 1. Utwórz klucz. W obszarze roboczym otwórz API i webhooki. Klucze stają się dostępne po pierwszym doładowaniu salda; każdy klucz jest wyświetlany tylko raz, więc skopiuj go lub zapisz jako plik tekstowy.
  2. 2. Sprawdź koszt. Wyślij tę samą treść metodą POST na /costs, aby zobaczyć odbiorców, segmenty i całkowity koszt bez wysyłania.
  3. 3. Wyślij. Wyślij treść metodą POST na /sends. Odpowiedź zawiera identyfikator wysyłki; wiadomości zostaną wysłane natychmiast lub o czasie send_at.
curl https://sendsmsonline.cc/api/v1/sends \
  -H "Authorization: Bearer $SSO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "recipients": [ { "to": "+447700900461", "fields": { "first_name": "Tom" } }, { "to": "+12015550142", "fields": { "first_name": "Ava" } } ], "text": "Hi {{first_name}}, your table is ready at 7:30.", "name": "Friday bookings", "client_ref": "bookings-1107" }'

Uwierzytelnianie

Wyślij swój klucz w nagłówku Authorization: Authorization: Bearer sso_live_.... Klucze mają 49 znaków i zaczynają się od sso_live_. Maksymalnie 5 kluczy na konto; odwołaj jeden w obszarze roboczym, a przestanie działać natychmiast. Cennik jest publiczny i nie wymaga klucza.

Błędy

Błędy wykorzystują kody statusu HTTP i treść JSON ze stabilnym kodem i zdaniem, które można pokazać osobie. Nic nie jest pobierane, gdy żądanie nie powiedzie się.

HTTP/1.1 402 Payment Required
{ "error": { "code": "insufficient_credit", "message": "Short by $3.20. Add funds to send.", "total": "8.62480", "credit": "5.42000" } }
PoleZnaczenie
400Żądanie wymaga zmiany.
401Brakujący, błędny lub odwołany klucz.
402Niewystarczające saldo na pokrycie całkowitego kosztu.
404Nie ma takiej wysyłki, wiadomości, kraju lub punktu końcowego.
409Wysyłka już się rozpoczęła.
429Więcej niż 240 żądań w ciągu minuty.

Limity

  • 240 żądań na minutę na klucz, pokazane w X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset (sekundy unix).
  • 5,000 numerów na żądanie, 2,000 znaków na tekst, 10 segmentów na wiadomość.
  • Wiadomości są wysyłane z maksymalną szybkością 300 na minutę na konto.
  • send_at od 10 minut do 30 dni w przód.

Ceny

GET/api/v1/prices

GET/api/v1/prices/{country}

Cena za wiadomość (jeden segment) dla każdego kraju, w USD z 5 miejscami po przecinku. Klucz nie jest wymagany.

{ "price": { "country": "GB", "name": "United Kingdom", "dial_code": "+44", "price_usd": "0.00868" }, "updated": "2026-11-07" }

Saldo konta

GET/api/v1/account

{ "account": "SO8K2M4Q7X9TBA", "credit_usd": "41.27660", "currency": "USD" }

Oszacuj koszt

POST/api/v1/costs

Przyjmuje te same dane co wysyłka i zwraca szacowany koszt, bez wysyłania lub pobierania opłat. Tekst po scaleniu dla każdego odbiorcy decyduje o segmentach, więc suma jest dokładna.

{
  "recipients": 2, "segments_min": 1, "segments_max": 1, "encoding": "gsm7", "messages_billed": 2,
  "total_usd": "0.01426", "credit_usd": "41.27660", "enough_credit": true,
  "countries": [ { "country": "GB", "recipients": 1, "price_usd": "0.00868", "subtotal_usd": "0.00868" },
                 { "country": "US", "recipients": 1, "price_usd": "0.00558", "subtotal_usd": "0.00558" } ],
  "dropped": [], "too_long": null
}

Utwórz wysyłkę

POST/api/v1/sends

Jeden tekst do jednego lub wielu numerów. Środki za całą wysyłkę są pobierane po zaakceptowaniu; nieudane wiadomości są zwracane jedna po drugiej.

PoleZnaczenie
toNumery w formacie międzynarodowym (+447700900461). Użyj tego lub odbiorców.
recipientsObiekty z to i fields, dla pól scalających: { "to": "+1...", "fields": { "first_name": "Ava" } }.
textWiadomość, do 2,000 znaków. {{field}} jest zastępowane dla każdego odbiorcy; brakujące wartości stają się puste.
send_atOpcjonalny czas ISO 8601 z przesunięciem lub Z. Bez niego wysyłka zaczyna się natychmiast.
nameOpcjonalna etykieta widoczna w obszarze roboczym (80 znaków).
client_refOpcjonalne odwołanie zwracane w webhookach (64 znaki).
opt_outDodaje linię rezygnacji zapisaną w Ustawieniach na końcu tekstu.
default_countryKod ISO używany dla numerów zapisanych bez kodu kraju.
HTTP/1.1 201 Created
{
  "send": { "id": "CA7Q29XMAB4DFK", "status": "queued", "source": "api", "recipients": 2, "segments_max": 1,
            "encoding": "gsm7", "cost_usd": "0.01426", "refunded_usd": "0.00000", "client_ref": "bookings-1107",
            "send_at": null, "created_at": "2026-11-07T10:12:03.120Z", "started_at": null, "finished_at": null },
  "dropped": [ { "value": "+4412", "code": "too_short", "message": "Too short" } ]
}

Numery, których nie można wysłać, są wymienione w dropped i nigdy nie są obciążane. Kody: no_country_code, too_short, too_long, not_a_number, wrong_length, not_covered, duplicate i suppressed (na liście nie wysyłaj).

Pobierz lub wyświetl wysyłki

GET/api/v1/sends/{id}

GET/api/v1/sends?limit=25&before={id}

Pojedyncza wysyłka zawiera counts dla każdego statusu wiadomości. Listy są uporządkowane od najnowszych; przekaż next_before jako before dla następnej strony. Wysyłki z obszaru roboczego również się tu pojawiają, z source: "web".

Wiadomości

GET/api/v1/sends/{id}/messages?status=failed&limit=100

GET/api/v1/messages/{id}

{ "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
  "segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
  "created_at": "2026-11-07T10:12:03.120Z", "sent_at": "2026-11-07T10:12:04.010Z", "done_at": "2026-11-07T10:12:09.400Z" } }

Anuluj wysyłkę

POST/api/v1/sends/{id}/cancel

Tylko zaplanowane wysyłki, które się nie rozpoczęły, można anulować. Pełny koszt wraca na saldo, a odpowiedź zawiera refunded_usd.

Webhooki

Ustaw URL https w obszarze roboczym (API i webhooki). Wysyłamy POST zdarzenia, gdy wiadomość zostanie dostarczona lub nie, zarówno dla wysyłek z API, jak i z obszaru roboczego. Odpowiedz z dowolnym statusem 2xx w ciągu 10 sekund. Nieudane dostawy są ponawiane do 7 razy: natychmiast, potem po 1 minucie, 5 minutach, 30 minutach, 1 godzinie, 2 godzinach i 3 godzinach. Obszar roboczy pokazuje każdą próbę z jej statusem i odpowiedzią.

POST https://your-server.example/sms-events
X-SSO-Event: message.delivered
X-SSO-Delivery: evt_5a0c9e31d2b7f4a68c
X-SSO-Timestamp: 1794132729
X-SSO-Signature: sha256=8f1c...e42a

{ "id": "evt_5a0c9e31d2b7f4a68c", "event": "message.delivered", "created": "2026-11-07T10:12:09.000Z",
  "data": { "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
  "segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
  "client_ref": "bookings-1107", "created_at": "...", "sent_at": "...", "done_at": "..." } } }

Podpis to HMAC-SHA256 z timestamp + "." + raw body z twoim sekretem podpisu (zaczyna się od sso_whk_). Sprawdź go na surowych danych przed parsowaniem, odrzuć znaczniki czasu starsze niż 5 minut i użyj delivery id, aby ignorować powtórzenia.

import crypto from "node:crypto";

// rawBody: the request body exactly as received (a string), before JSON.parse
export function verify(rawBody, headers, secret) {
  const ts = headers["x-sso-timestamp"];
  const sig = headers["x-sso-signature"] || "";
  const want = "sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === want.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}

Zdarzenia: message.delivered, message.failed i test z przycisku Wyślij testowe zdarzenie.

Statusy i powody

PoleZnaczenie
queuedOczekiwanie na opuszczenie kolejki.
sentPrzekazane do sieci, oczekiwanie na raport dostarczenia. Większość raportów przychodzi w ciągu kilku minut; niektóre sieci mogą zająć do 24 godzin.
deliveredSieć potwierdziła, że telefon otrzymał wiadomość.
failedNie dostarczono. Kwota została zwrócona na Twoje saldo.
canceledNie wysłano, ponieważ anulowano. Zwrócono środki.

Przyczyny niepowodzenia (pole reason):

PoleZnaczenie
network_errorBłąd sieci
absentTelefon wyłączony lub poza zasięgiem
not_in_serviceNumer nieaktywny
blockedZablokowane przez sieć lub odbiorcę
landlineTelefon stacjonarny lub numer, który nie może odbierać SMS
content_filterOdrzucone przez filtr treści sieci
expiredPrzedawnione: brak raportu przed limitem czasu sieci
canceledAnulowane przed wysłaniem
unknownNieznana odpowiedź sieci

Sprawdzenia usług znajdują się na stronie statusu, a zmiany API w changelogu.

Pobierz swój klucz API

Utwórz konto, doładuj środki raz i otwórz API oraz webhooki w obszarze roboczym. Ten sam klucz działa w każdym kraju.

Utwórz darmowe konto
Dokumentacja API SMS: Wysyłaj masowe SMS-y z Twojego kodu | SendSMSOnline