コンテンツへスキップ
smsbulk

一括SMS API v1

独自のソフトウェアからバルクSMSを送信するための小型REST API: JSON入出力、Bearerキー、コンソールと同じ価格とチェック、配信レポートのための署名付きウェブフック。 ベースURL https://smsbulk.cc/rest/v1

概要

1リクエストあたり最大8,000件の番号に送信し、それぞれに独自のマージ値を設定できます。APIはコンソールと同様に、各受信者のマージされたテキストに基づいて価格を計算します。まず同じ本文で見積もりをリクエストしてコストを確認してください。見積もりでは何も送信されず、課金も発生しません。時間はISO 8601形式でUTC、金額は5桁の小数部を持つUSドルの文字列です。

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とウェブフックの下でキーを作成します。初回のクレジットチャージ後にキーが有効になります。すべてのリクエストでBearerトークンとして送信してください。キーは一度だけ表示されます。最大5個のキーを保持でき、いつでも任意のキーを無効にできます。

Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

料金

公開されており、キーは不要です。すべての宛先または1つのISOコードに対するSMSセグメントごとの価格です。

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

フィールド意味
to1つの番号またはリスト。+付きの国際形式が最も安全です。ローカル番号にはdefault_countryが必要です。
recipientstoの代わりに、fieldsが{{name}}などのマージフィールドを埋める{ to, fields }のリスト。
textメッセージは、マージ後2,000文字、10セグメントまで。
default_country+なしで書かれた番号(GBなど)に使用されるISOコード。設定に保存されたデフォルトにフォールバックします。
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_outQuoteと同様。
send_at開始するISO 8601時間、5分から90日前。省略するとすぐに送信します。
nameキャンペーンのラベル、最大80文字。
client_ref独自の参照、最大64文字、すべてのメッセージとウェブフックで返されます。
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}

1つのキャンペーンには、キューに入れられた、送信された、配信された、失敗した、キャンセルされた各ステータスのカウントが含まれます。メッセージリストページはafterとhas_moreでページングされ、1ページあたり最大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

開始時刻まで有効です。全額が1つの台帳行としてクレジットに戻り、キャンペーンステータスがキャンセルになります。

ウェブフック

コンソールでエンドポイントURLを設定します。message.delivered、message.failed、campaign.doneのJSONをPOSTし、Send test eventを押すとテストも送信します。各イベントには4つのヘッダーが付き、10秒以内の2xx応答は受信済みとみなされます。

フィールド意味
Smsbulk-Eventmessage.deliveredなどのイベント名。
Smsbulk-Delivery配信ID、1つのイベントの再試行ごとに同じ。
Smsbulk-Timestampこの試行が署名されたUnix秒。
Smsbulk-Signaturesha256=に続いて、タイムスタンプ、改行、および生の本文のbase64 HMAC-SHA256、sbw_シークレットでキー化されます。

配信は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このキーに対して1分間に300回以上のリクエストがあります。

すべての回答にはX-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Resetが含まれます。

除外コード

価格設定前に削除された番号は、left_outにリスト内の位置、送信した値、コード、および理由とともに返されます。

フィールド意味
no_country_code+がなく、デフォルトの国もありません。
too_short / too_long8桁未満または15桁を超えています。
not_a_number数字の一部ではない文字や記号があります。
nanp_length11桁ではない +1 の番号です。
not_coveredリスト外の宛先です。
duplicate同じ番号がリクエストの前半に出現しました。
suppressedその番号は送信禁止リストにあります。

ステータスと理由

フィールド意味
queuedキューから出るのを待っています。
sentネットワークに渡され、配信レポートを待っています。ほとんどのレポートは数分以内に到着しますが、一部のネットワークでは24時間かかることがあります。
deliveredネットワークが電話に届いたことを確認しました。
failed配信されませんでした。料金はクレジットに返金されました。
canceledキャンセルしたため送信されませんでした。返金されました。
フィールド意味
network_errorネットワークエラー
switched_off電話がオフまたは圏外です
not_in_serviceサービス外の番号です
blockedネットワークまたは受信者によってブロックされました
landlineSMSを受信できない固定電話または番号
content_filterネットワークのコンテンツフィルターによって拒否されました
expired期限切れ: ネットワークの制限時間内にレポートがありませんでした
unknown不明なネットワーク応答
canceled送信前にキャンセルされました

APIについての質問ですか?コンソールでチケットを開くか、FAQを読んでください。

Bulk SMS API v1 ドキュメント: 送信、見積もり、Webhooks | SMSBulk