跳至內容
smsbulk

大量 SMS API v1

一個簡潔的REST API,讓您能從自己的軟體發送大量簡訊:使用JSON格式輸入輸出、Bearer金鑰,價格與檢查機制與網頁控制台相同,並提供簽章驗證的webhook接收送達報告。 基礎URL https://smsbulk.cc/rest/v1

概述

每個請求最多可發送至8,000個號碼,每個號碼可帶入各自的合併欄位值。API會像控制台一樣,根據每位收件者合併後的文字內容精確計算費用。發送前可先使用相同內容取得報價,報價不會實際發送或收費。時間格式為ISO 8601標準(UTC時區),金額以五位小數的美金字串表示。

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"
  }'

認證

在控制台的API與webhook區建立金鑰,首次儲值後金鑰才會生效。每次請求需以Bearer token形式攜帶金鑰。金鑰僅顯示一次,您最多可保留5組金鑰並隨時撤銷任一組。

Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

費率

公開API無需金鑰。查詢所有目的地或指定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"
}

餘額

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

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

報價

模擬發送並計算費用,參數格式與Send相同但不會實際發送。

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

欄位意義
to可為單一號碼或清單。使用國際格式(含+號)最安全;本地號碼需指定 default_country。
recipients可替代 to:使用 { to, fields } 清單,其中 fields 用於填充合併欄位如 {{name}}。
text訊息內容,合併後最多 2,000 個字元與 10 個分段。
default_country用於未帶+號的號碼之ISO代碼(如GB)。若未指定則退回設定中儲存的預設值。
opt_out將您儲存的退訂聲明添加為最後一行(需先在設定中儲存)。
{
  "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": []
}

發送

建立發送任務,從餘額扣除總費用並將訊息排入佇列。回傳201狀態碼及任務資料。無法發送的號碼會列於left_out欄位且不計費。

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

欄位意義
to / recipients / text / default_country / opt_out同報價功能。
send_at以ISO 8601格式指定開始時間,可設定5分鐘後至90天內。留空則立即發送。
name活動標籤,最多80個字元。
client_ref自訂參考代號(最多64字元),將隨每則訊息及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": []
}

發送任務

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}

單一發送任務包含各狀態計數:排隊中、已發送、已送達、失敗與已取消。訊息列表支援分頁查詢(after與has_more參數),每頁最多1,000筆。

訊息

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"
}

取消預約發送

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

在預定發送時間前可取消,全額費用將以單一紀錄返還至您的餘額,任務狀態變更為已取消。

Webhook

在控制台設定接收URL端點。我們會POST JSON格式的message.delivered(送達)、message.failed(失敗)與campaign.done(任務完成)事件,點擊「發送測試事件」時也會觸發測試。每個事件帶有四個標頭,10秒內回傳2xx狀態碼即視為接收成功。

欄位意義
Smsbulk-Event事件名稱,例如 message.delivered。
Smsbulk-Delivery遞送ID,同一事件每次重試時保持相同。
Smsbulk-Timestamp此嘗試簽署時的Unix時間戳(秒)。
Smsbulk-Signaturesha256= 後接以您 sbw_ 密鑰對時間戳、換行符及原始主體進行HMAC-SHA256運算後的base64值。

系統會嘗試發送8次:立即發送後,分別於1分鐘、5分鐘、15分鐘、1小時、3小時、6小時和12小時後重試。每次嘗試皆會記錄於控制台的傳送日誌,包含HTTP狀態碼與您的回傳內容開頭。

{
  "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"
  }
}

驗證簽名

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));
}

錯誤與限制

錯誤會使用 HTTP 狀態碼和 JSON 回應主體:{"error":{"code":"insufficient_credit","message":"..."}}。請求失敗時不會收取任何費用。

欄位意義
400 bad_json主體非JSON格式。
401 unauthorized密鑰遺失、格式錯誤或已撤銷。
402 insufficient_credit總金額超過您的餘額。請在控制台中充值。
404 not_found此帳戶中沒有此端點、活動、訊息或ISO代碼。
409 not_scheduled已開始的活動被要求取消。
422 text_missing, text_too_long, too_many_segments訊息為空、超過2,000個字符,或對一個收件人超過10個分段。
422 no_recipients, too_many, recipients_missing無可發送號碼、超過8,000個號碼,或既無to也無recipients。
422 schedule_range, bad_send_atsend_at在5分鐘到90天之外,或不是有效時間。
422 opt_out_unsetopt_out為true但設置中未保存相關文字。
429 rate_limited此密鑰每分鐘請求超過300次。

每個回應都會包含 X-RateLimit-Limit、X-RateLimit-Remaining 和 X-RateLimit-Reset。

排除的號碼

在計價前被移除的號碼會以 left_out 形式回傳,包含其在清單中的位置、您傳送的值、代碼及簡明原因。

欄位意義
no_country_code無+且無默認國家。
too_short / too_long少於8位或多於15位。
not_a_number不屬於數字的字母或符號。
nanp_length不足 11 位數的 +1 號碼。
not_covered目的地不在我們的列表中。
duplicate請求中之前出現過相同的號碼。
suppressed此號碼在您的禁止發送列表中。

狀態與原因

欄位意義
queued等待離開我們的隊列。
sent已交給網絡,等待送達報告。大多數報告在幾分鐘內到達;某些網絡可能需要長達24小時。
delivered網絡確認手機已收到。
failed未送達。價格已退還至您的餘額。
canceled因您取消而未發送。已退款。
欄位意義
network_error網絡錯誤
switched_off手機關機或不在服務範圍內
not_in_service號碼已停用
blocked被電信商或收件人封鎖
landline固網電話或無法接收簡訊的號碼
content_filter被電信商內容過濾系統拒絕
expired已過期:在電信商時限內未收到回報
unknown未知的電信商回應
canceled發送前已取消

對 API 有疑問?請在控制台提交問題單,或閱讀常見問答。

大量簡訊API v1文件:發送、報價、Webhooks | SMSBulk