ข้ามไปที่เนื้อหา
smsbulk

Bulk SMS API v1

API ขนาดเล็กสำหรับส่ง SMS แบบกลุ่มจากซอฟต์แวร์ของคุณเอง: JSON เข้าและออก, Bearer keys, ราคาและการตรวจสอบเดียวกับคอนโซล, และ webhooks ที่ลงลายเซ็นสำหรับรายงานการส่ง Base 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 และ webhooks คีย์จะเปิดใช้งานหลังจากเติมเครดิตครั้งแรก ส่งคีย์นี้ในทุกคำขอเป็น Bearer token คีย์จะแสดงเพียงครั้งเดียว คุณสามารถเก็บคีย์ได้ถึง 5 คีย์และยกเลิกคีย์ใดก็ได้ทันที

Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

อัตรา

สาธารณะ ไม่ต้องใช้คีย์ ราคาต่อ SMS segment สำหรับทุกปลายทาง หรือสำหรับรหัส 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 จะย้อนกลับไปใช้ค่าเริ่มต้นที่บันทึกไว้ใน Settings
opt_outเพิ่มข้อความยกเลิกการรับของคุณเป็นบรรทัดสุดท้าย (บันทึกไว้ใน Settings ก่อน)
{
  "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ตามที่อยู่ใน Quote
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}

แคมเปญเดียวรวมจำนวนต่อสถานะ: เข้าคิว, ส่งแล้ว, ส่งถึงแล้ว, ล้มเหลว และยกเลิก หน้ารายการข้อความมี 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

ทำงานจนถึงเวลาเริ่มต้น ค่าใช้จ่ายทั้งหมดจะคืนสู่เครดิตของคุณในหนึ่งบรรทัดบัญชี และสถานะแคมเปญจะเปลี่ยนเป็นยกเลิก

เว็บฮุค

ตั้งค่า endpoint URL ในคอนโซล เราจะ POST JSON สำหรับ message.delivered, message.failed และ campaign.done รวมถึงทดสอบเมื่อคุณกด Send test event แต่ละเหตุการณ์มีสี่ส่วนหัว และคำตอบใดๆ ที่เป็น 2xx ภายใน 10 วินาทีจะนับว่าได้รับแล้ว

ฟิลด์ความหมาย
Smsbulk-Eventชื่อเหตุการณ์ เช่น message.delivered
Smsbulk-Deliveryรหัสการจัดส่ง เหมือนกันทุกครั้งที่ลองใหม่ของเหตุการณ์หนึ่ง
Smsbulk-Timestampวินาที Unix เมื่อการพยายามนี้ถูกเซ็น
Smsbulk-Signaturesha256= ตามด้วย base64 HMAC-SHA256 ของ timestamp, ขึ้นบรรทัดใหม่และเนื้อหาดิบ ใช้คีย์ sbw_ secret ของคุณ

การส่งจะถูกลอง 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ไม่พบ endpoint, campaign, message หรือรหัส ISO ในบัญชีนี้
409 not_scheduledมีการขอยกเลิก campaign ที่เริ่มต้นไปแล้ว
422 text_missing, text_too_long, too_many_segmentsข้อความว่างเปล่า, เกิน 2,000 ตัวอักษร, หรือเกิน 10 segments สำหรับผู้รับ
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 เป็นจริงแต่ไม่มีข้อความที่บันทึกไว้ใน Settings
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หมายเลข +1 ที่ไม่มีสิบเอ็ดหลัก
not_coveredปลายทางไม่อยู่ในรายการของเรา
duplicateหมายเลขเดียวกันปรากฏก่อนหน้านี้ในคำขอ
suppressedหมายเลขนี้อยู่ในรายการห้ามส่งของคุณ

สถานะและเหตุผล

ฟิลด์ความหมาย
queuedกำลังรอออกจากคิวของเรา
sentส่งให้เครือข่ายแล้ว กำลังรอรายงานการส่ง รายงานส่วนใหญ่มาภายในไม่กี่นาที; บางเครือข่ายใช้เวลาถึง 24 ชั่วโมง
deliveredเครือข่ายยืนยันว่าโทรศัพท์ได้รับข้อความแล้ว
failedไม่สามารถส่งได้ ราคาถูกคืนเข้าสู่เครดิตของคุณ
canceledไม่ถูกส่งเนื่องจากคุณยกเลิก ได้รับเงินคืนแล้ว
ฟิลด์ความหมาย
network_errorข้อผิดพลาดของเครือข่าย
switched_offโทรศัพท์ปิดหรืออยู่นอกพื้นที่ครอบคลุม
not_in_serviceหมายเลขไม่ให้บริการ
blockedถูกบล็อกโดยเครือข่ายหรือผู้รับ
landlineเบอร์บ้านหรือเบอร์ที่ไม่สามารถรับ SMS ได้
content_filterถูกปฏิเสธโดยตัวกรองเนื้อหาของเครือข่าย
expiredหมดอายุ: ไม่มีรายงานก่อนเวลาที่เครือข่ายกำหนด
unknownไม่ทราบการตอบสนองจากเครือข่าย
canceledยกเลิกก่อนส่ง

มีคำถามเกี่ยวกับ API? เปิดตั๋วในคอนโซล หรืออ่าน FAQ

เอกสาร API v1 สำหรับส่ง SMS แบบกลุ่ม: ส่ง, คำนวนราคา, Webhooks | SMSBulk