Langkau ke kandungan
smsbulk

API SMS Pukal v1

API REST kecil untuk menghantar SMS pukal daripada perisian anda sendiri: JSON masuk dan keluar, kunci Bearer, harga dan semakan yang sama seperti konsol, dan webhook yang ditandatangani untuk laporan penghantaran. URL Asas https://smsbulk.cc/rest/v1

Gambaran Keseluruhan

Hantar sehingga 8,000 nombor setiap permintaan, setiap satu dengan nilai gabungan sendiri, dan API memberi harga setiap penerima dengan teks gabungan mereka sendiri, sama seperti konsol. Minta sebut harga dahulu dengan badan yang sama untuk mengetahui kos; tiada apa yang dihantar atau dicaj oleh sebut harga. Masa adalah ISO 8601 dalam UTC, wang adalah rentetan dalam dolar AS dengan lima perpuluhan.

curl https://smsbulk.cc/rest/v1/send \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      { "to": "+14155550142", "fields": { "name": "Maria" } },
      { "to": "+447400123456", "fields": { "name": "Tom" } }
    ],
    "text": "Hi {{name}}, your order ships today.",
    "client_ref": "order-batch-17"
  }'

Pengesahan

Buat kunci dalam konsol di bawah API dan webhook; kunci dibuka selepas top-up pertama anda yang dikreditkan. Hantarkannya pada setiap permintaan sebagai token Bearer. Kunci ditunjukkan sekali; anda boleh menyimpan sehingga 5 kunci dan membatalkan mana-mana daripadanya sekaligus.

Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Kadar

Awam, tiada kunci diperlukan. Harga setiap segmen SMS untuk setiap destinasi, atau untuk satu kod ISO.

GEThttps://smsbulk.cc/rest/v1/rates

GEThttps://smsbulk.cc/rest/v1/rates/{ISO}

{
  "country": "US",
  "name": "United States",
  "dial_code": "+1",
  "rate": "0.00485",
  "currency": "USD",
  "per": "message segment"
}

Kredit

GEThttps://smsbulk.cc/rest/v1/credit

{ "credit": "125.40000", "currency": "USD", "account": "A418820037715" }

Sebut Harga

Memberi harga penghantaran tanpa menghantarnya. Mengambil badan yang sama seperti Hantar.

POSThttps://smsbulk.cc/rest/v1/quote

MedanMaksud
toSatu nombor atau senarai. Bentuk antarabangsa dengan + adalah paling selamat; nombor tempatan memerlukan default_country.
recipientsSebagai ganti kepada: senarai { to, fields } di mana medan mengisi medan gabungan seperti {{name}}.
textMesej tersebut, sehingga 2,000 aksara dan 10 segmen selepas penggabungan.
default_countryKod ISO digunakan untuk nombor yang ditulis tanpa +, seperti GB. Kembali ke lalai yang disimpan dalam Tetapan.
opt_outMenambah wording opt-out yang anda simpan sebagai baris terakhir (simpan dalam Tetapan dahulu).
{
  "recipients": 2,
  "messages": 2,
  "segments": { "min": 1, "max": 1 },
  "encoding": "GSM-7",
  "total": "0.01240",
  "currency": "USD",
  "credit": "125.40000",
  "credit_after": "125.38760",
  "countries": [
    { "country": "US", "recipients": 1, "rate": "0.00485", "segments": 1, "subtotal": "0.00485" },
    { "country": "GB", "recipients": 1, "rate": "0.00755", "segments": 1, "subtotal": "0.00755" }
  ],
  "left_out": []
}

Hantar

Mencipta kempen, mengambil jumlahnya daripada kredit anda dan mengatur giliran mesej. Menjawab 201 dengan kempen. Nombor yang tidak dapat dihantar disenaraikan dalam left_out dan tidak pernah dicaj.

POSThttps://smsbulk.cc/rest/v1/send

MedanMaksud
to / recipients / text / default_country / opt_outSeperti dalam Quote.
send_atMasa ISO 8601 untuk bermula, 5 minit hingga 90 hari ke hadapan. Tinggalkan untuk hantar sekarang.
nameLabel anda untuk kempen, sehingga 80 aksara.
client_refRujukan anda sendiri, sehingga 64 aksara, dikembalikan pada setiap mesej dan webhook.
HTTP/1.1 201 Created
{
  "campaign": {
    "id": "C507318264409",
    "name": null,
    "status": "sending",
    "source": "api",
    "test": false,
    "recipients": 2,
    "cost": "0.01240",
    "refunded": "0.00000",
    "net_cost": "0.01240",
    "currency": "USD",
    "send_at": null,
    "created_at": "2026-11-07T14:02:11.000Z",
    "started_at": "2026-11-07T14:02:11.000Z",
    "finished_at": null,
    "client_ref": "order-batch-17"
  },
  "messages": 2,
  "left_out": []
}

Kempen

GEThttps://smsbulk.cc/rest/v1/campaigns?limit=25&before={id}

GEThttps://smsbulk.cc/rest/v1/campaigns/{id}

GEThttps://smsbulk.cc/rest/v1/campaigns/{id}/messages?status=failed&limit=100&after={message id}

Satu kempen termasuk kiraan setiap status: dalam giliran, dihantar, dihantar, gagal dan dibatalkan. Halaman senarai mesej dengan after dan has_more; sehingga 1,000 setiap halaman.

Mesej

GEThttps://smsbulk.cc/rest/v1/messages/{id}

GEThttps://smsbulk.cc/rest/v1/messages?to=%2B14155550142&status=delivered&client_ref=order-batch-17&limit=50

{
  "id": "M220947781305",
  "campaign": "C507318264409",
  "to": "+14155550142",
  "country": "US",
  "segments": 1,
  "encoding": "GSM-7",
  "price": "0.00485",
  "status": "delivered",
  "reason": null,
  "reason_text": null,
  "refunded": false,
  "client_ref": "order-batch-17",
  "created_at": "2026-11-07T14:02:11.000Z",
  "sent_at": "2026-11-07T14:02:12.000Z",
  "finished_at": "2026-11-07T14:02:16.000Z"
}

Batalkan kempen yang dijadualkan

POSThttps://smsbulk.cc/rest/v1/campaigns/{id}/cancel

Berfungsi sehingga masa mula. Keseluruhan kos kembali ke kredit anda dalam satu baris lejar dan status kempen menjadi dibatalkan.

Webhook

Tetapkan URL endpoint dalam konsol. Kami POST JSON untuk message.delivered, message.failed dan campaign.done, tambah ujian apabila anda menekan Hantar ujian acara. Setiap acara membawa empat pengepala, dan sebarang jawapan 2xx dalam 10 saat dikira sebagai diterima.

MedanMaksud
Smsbulk-EventNama acara, seperti message.delivered.
Smsbulk-DeliveryID penghantaran, sama pada setiap percubaan semula satu acara.
Smsbulk-TimestampSaat Unix apabila percubaan ini ditandatangani.
Smsbulk-Signaturesha256= diikuti oleh base64 HMAC-SHA256 daripada timestamp, baris baru dan badan mentah, dikunci dengan rahsia sbw_ anda.

Penghantaran dicuba 8 kali: sekaligus, kemudian selepas 1 minit, 5 minit, 15 minit, 1 jam, 3 jam, 6 jam dan 12 jam. Setiap percubaan ditunjukkan dalam log penghantaran konsol dengan status HTTP dan permulaan jawapan anda.

{
  "id": "dlv_3f9a1c07b2e44d58a6c1",
  "event": "message.failed",
  "created": "2026-11-07T14:02:16.000Z",
  "data": {
    "message": "M220947781305",
    "campaign": "C507318264409",
    "to": "+447400123456",
    "country": "GB",
    "status": "failed",
    "reason": "not_in_service",
    "segments": 1,
    "price": "0.00755",
    "client_ref": "order-batch-17"
  }
}

Sahkan tandatangan

import crypto from "node:crypto";

// raw = the request body exactly as received (string), secret = your sbw_ signing secret
export function verify(raw, headers, secret) {
  const ts = headers["smsbulk-timestamp"];
  const want = "sha256=" + crypto.createHmac("sha256", secret).update(ts + "\n" + raw).digest("base64");
  const got = headers["smsbulk-signature"] || "";
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && got.length === want.length && crypto.timingSafeEqual(Buffer.from(got), Buffer.from(want));
}

Ralat dan Had

Ralat menggunakan status HTTP dan badan JSON: {"error":{"code":"insufficient_credit","message":"..."}}. Tiada caj dikenakan apabila permintaan gagal.

MedanMaksud
400 bad_jsonBadan tersebut bukan JSON.
401 unauthorizedKunci hilang, rosak atau dibatalkan.
402 insufficient_creditJumlah melebihi saldo anda. Tambah dana dalam konsol.
404 not_foundTiada endpoint, kempen, mesej atau kod ISO tersebut dalam akaun ini.
409 not_scheduledPembatalan diminta untuk kempen yang telah bermula.
422 text_missing, text_too_long, too_many_segmentsMesej kosong, melebihi 2,000 aksara, atau melebihi 10 segmen untuk penerima.
422 no_recipients, too_many, recipients_missingTiada nombor yang boleh dihantar, lebih daripada 8,000 nombor, atau tiada penerima atau 'to'.
422 schedule_range, bad_send_atsend_at di luar 5 minit hingga 90 hari, atau bukan masa yang sah.
422 opt_out_unsetopt_out adalah benar tetapi tiada teks disimpan dalam Tetapan.
429 rate_limitedLebih daripada 300 permintaan dalam seminit untuk kunci ini.

Setiap jawapan membawa X-RateLimit-Limit, X-RateLimit-Remaining dan X-RateLimit-Reset.

Kod yang ditinggalkan

Nombor yang dikeluarkan sebelum penetapan harga dikembalikan dalam left_out dengan kedudukan mereka dalam senarai anda, nilai yang anda hantar, kod dan sebab yang jelas.

MedanMaksud
no_country_codeTiada + dan tiada negara lalai.
too_short / too_longKurang daripada 8 atau lebih daripada 15 digit.
not_a_numberHuruf atau simbol yang bukan sebahagian daripada nombor.
nanp_lengthNombor +1 tanpa sebelas digit.
not_coveredDestinasi di luar senarai kami.
duplicateNombor yang sama muncul lebih awal dalam permintaan.
suppressedNombor tersebut berada dalam senarai jangan hantar anda.

Status dan sebab

MedanMaksud
queuedMenunggu untuk keluar dari barisan kami.
sentDiserahkan kepada rangkaian, menunggu laporan penghantaran. Kebanyakan laporan tiba dalam beberapa minit; sesetengah rangkaian mengambil masa sehingga 24 jam.
deliveredRangkaian mengesahkan telefon menerimanya.
failedTidak dihantar. Harga telah dikembalikan ke saldo anda.
canceledTidak dihantar kerana anda membatalkan. Dikembalikan.
MedanMaksud
network_errorRalat rangkaian
switched_offTelefon dimatikan atau di luar liputan
not_in_serviceNombor tidak berfungsi
blockedDisekat oleh rangkaian atau penerima
landlineTalian tetap atau nombor yang tidak boleh menerima SMS
content_filterDitolak oleh penapis kandungan rangkaian
expiredTamat tempoh: tiada laporan sebelum had masa rangkaian
unknownTindak balas rangkaian tidak diketahui
canceledDibatalkan sebelum dihantar

Soalan mengenai API? Buka tiket dalam konsol, atau baca FAQ.

Dokumentasi API SMS Bulk v1: Hantar, Sebut Harga, Webhooks | SMSBulk