เอกสารอ้างอิง API สำหรับ SMS จำนวนมาก

REST API ของ BulkSMSOnline ส่งข้อความไปยัง 227 ประเทศจากซอฟต์แวร์ของคุณเอง ด้วยราคา กฎเซกเมนต์ การตั้งเวลา และการคืนเงินเหมือนคอนโซล คำขอและการตอบกลับเป็น JSON ผ่าน HTTPS และสถานะสุดท้ายของทุกการส่งสามารถส่งไปยังเซิร์ฟเวอร์ของคุณเป็น webhook แบบมีลายเซ็น

Base URLhttps://bulksmsonline.cc/api/v1

ภาพรวม

ใช้ API เมื่อข้อความถูกสั่งส่งจากระบบของคุณเอง: อัปเดตคำสั่งซื้อจากร้านค้า รหัสจากแบบฟอร์มเข้าสู่ระบบ การเตือนจากเครื่องมือจองคิว คำขอ POST /v1/messages ที่มีสูงสุด 10,000 หมายเลขจะสร้างหนึ่งแคมเปญ หักยอดเงิน และจัดทุกข้อความเข้าคิว แคมเปญที่สร้างด้วย API ก็ปรากฏในคอนโซลพร้อมรายงานการส่งเช่นกัน

  • จำนวนเงินทั้งหมดเป็นดอลลาร์สหรัฐในรูปสตริงที่มีทศนิยมห้าตำแหน่ง เช่น "0.00534"
  • หมายเลขโทรศัพท์เป็นรูปแบบสากล จะมี + นำหน้าหรือไม่ก็ได้ ช่องว่างและขีดกลางจะถูกลบ
  • เวลาเป็นแบบ ISO 8601 ใน UTC เช่น 2026-12-01T09:00:00Z
  • ID ของข้อความและแคมเปญมีลักษณะเป็น MSG-XXXX-XXXX-XXXX และ CMP-XXXX-XXXX-XXXX

การยืนยันตัวตน

สร้างคีย์ API ใต้ API ในคอนโซล (คีย์จะเปิดใช้หลังจากเพิ่มการเติมเงินครั้งแรกแล้ว) ส่งคีย์ในส่วนหัว Authorization ของทุกคำขอ คีย์มีลักษณะเป็น bso_api_ ตามด้วย 36 อักขระ แสดงเพียงครั้งเดียว จึงควรเก็บเป็นความลับบนเซิร์ฟเวอร์ของคุณ การสร้างคีย์ใหม่จะแทนที่คีย์เดิมทันที

Authorization: Bearer bso_api_0123456789abcdef0123456789abcdef0123
Content-Type: application/json

ขีดจำกัด

คำขอ300 ต่อนาทีต่อคีย์ เกินกว่านั้นตอบ 429 rate_limited
หมายเลขต่อคำขอ10,000
ข้อความ2,000 อักขระตามที่เขียน สูงสุด 10 เซกเมนต์
การตั้งเวลาsend_at ตั้งแต่ 5 นาทีถึง 60 วันล่วงหน้า
ความเร็วในการส่ง400 ข้อความต่อนาทีต่อคิว
การลองส่ง webhook ซ้ำ9 ครั้งในเวลาประมาณ 22 ชั่วโมง

ส่งข้อความ

POST/v1/messages

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

ฟิลด์คำอธิบาย
toจำเป็นหนึ่งหมายเลขหรืออาร์เรย์ของหมายเลขสูงสุด 10,000 หมายเลขในรูปแบบสากล หมายเลขที่ซ้ำจะส่งครั้งเดียว หมายเลขที่อ่านไม่ได้จะแสดงใน skipped
textจำเป็นข้อความ สูงสุด 2,000 อักขระและ 10 เซกเมนต์ ข้อความ GSM-7 บรรจุ 160 อักขระต่อ SMS ส่วน Unicode บรรจุ 70
send_atไม่บังคับเวลาแบบ ISO 8601 เพื่อตั้งเวลาส่ง ตั้งแต่ 5 นาทีถึง 60 วันล่วงหน้า เว้นไว้เพื่อส่งทันที
opt_outไม่บังคับtrue จะเพิ่มบรรทัดยกเลิกการรับข้อความจากการตั้งค่าคอนโซลของคุณในบรรทัดใหม่ท้ายข้อความ
client_refไม่บังคับข้อมูลอ้างอิงของคุณเอง สูงสุด 64 ตัวอักษร ตัวเลข และ _ . : - จะถูกส่งคืนในรายงานและ webhook
curl -X POST https://bulksmsonline.cc/api/v1/messages \
  -H "Authorization: Bearer $BSO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":["+447700900412","+33612345678"],"text":"Order 4521 has shipped. Track it at shop.example/t/4521","client_ref":"order-4521"}'
HTTP/1.1 201 Created
{
  "id": "CMP-7KQ2-M9XA-4HTD",
  "status": "sending",
  "channel": "api",
  "recipients": 2,
  "segments": 1,
  "encoding": "GSM-7",
  "cost": "0.02158",
  "refunded": "0.00000",
  "client_ref": "order-4521",
  "send_at": null,
  "counts": { "queued": 2, "submitted": 0, "delivered": 0, "failed": 0, "canceled": 0 },
  "skipped": [],
  "balance": "118.43120",
  "messages": [
    { "id": "MSG-3RTW-81KD-ZQ0P", "to": "+447700900412", "country": "GB", "segments": 1, "price": "0.00834", "status": "queued" },
    { "id": "MSG-5HNA-4C2E-7YVB", "to": "+33612345678", "country": "FR", "segments": 1, "price": "0.01324", "status": "queued" }
  ]
}

ประเมินราคาการส่ง

POST/v1/quote

ใช้เนื้อหาเดียวกับ /v1/messages และส่งคืนค่าใช้จ่ายที่แน่นอน เซกเมนต์ และการเข้ารหัสโดยไม่ส่งและไม่หักเงิน ใช้เพื่อแสดงราคาให้ผู้ใช้ของคุณเห็นก่อนที่พวกเขาจะยืนยัน

{
  "recipients": 2,
  "skipped": [],
  "segments": 1,
  "encoding": "GSM-7",
  "cost": "0.02158",
  "balance": "118.45278",
  "countries": [ { "country": "GB", "recipients": 1, "cost": "0.00834" }, { "country": "FR", "recipients": 1, "cost": "0.01324" } ]
}

ยอดเงิน

GET/v1/balance

{ "balance": "118.43120", "currency": "USD" }

อัตราราคา

GET/v1/rates

GET/v1/rates/{country}

ราคาของหนึ่งเซกเมนต์ SMS สำหรับทุกปลายทาง หรือสำหรับรหัสประเทศ ISO สองตัวอักษรหนึ่งประเทศ สองเอ็นด์พอยต์นี้เป็นสาธารณะและไม่ต้องใช้คีย์

{ "country": "DE", "name": "Germany", "calling_code": "+49", "price": "0.01544", "currency": "USD", "per": "segment" }

สถานะข้อความ

GET/v1/messages/{id}

{
  "id": "MSG-3RTW-81KD-ZQ0P",
  "campaign_id": "CMP-7KQ2-M9XA-4HTD",
  "to": "+447700900412",
  "country": "GB",
  "segments": 1,
  "price": "0.00834",
  "status": "delivered",
  "error": null,
  "created_at": "2026-11-07T09:00:02Z",
  "submitted_at": "2026-11-07T09:00:03Z",
  "final_at": "2026-11-07T09:00:08Z"
}

แคมเปญ

GET/v1/campaigns/{id}

GET/v1/campaigns/{id}/messages?offset=0&limit=100

รายการแรกส่งคืนแคมเปญพร้อมจำนวนตามสถานะ รายการที่สองแบ่งหน้าข้อความของแคมเปญ สูงสุด 1,000 ต่อหน้า แคมเปญที่ส่งจากคอนโซลอ่านได้ด้วยวิธีเดียวกันโดยใช้ ID ที่แสดงในหน้าของแคมเปญ

ยกเลิกการส่งที่ตั้งเวลาไว้

POST/v1/campaigns/{id}/cancel

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

Webhook รายงานการส่ง

เพิ่ม URL แบบ HTTPS ใต้ API ในคอนโซลเพื่อรับสถานะสุดท้ายแต่ละรายการ (delivered หรือ failed) เป็นคำขอ POST ตอบกลับด้วยสถานะ 2xx ใดก็ได้ภายใน 8 วินาที คำตอบอื่นและการหมดเวลาจะลองใหม่หลัง 20 วินาที 1, 5 และ 15 นาที จากนั้น 1, 3, 6 และ 12 ชั่วโมง รวม 9 ครั้ง เหตุการณ์เดียวกันอาจมาถึงสองครั้ง จึงควรใช้ event_id เพื่อประมวลผลเพียงครั้งเดียว

POST https://your-server.example/sms-status
Content-Type: application/json
X-BulkSMSOnline-Signature: t=1794042008,v1=5f0c2a...e91b

{
  "type": "message.status",
  "event_id": "ev_8f1c22d0a4b97e63c1f0",
  "sent_at": "2026-11-07T09:00:09Z",
  "data": {
    "message_id": "MSG-3RTW-81KD-ZQ0P",
    "campaign_id": "CMP-7KQ2-M9XA-4HTD",
    "to": "+447700900412",
    "country": "GB",
    "status": "delivered",
    "error": null,
    "segments": 1,
    "price": "0.00834",
    "currency": "USD",
    "client_ref": "order-4521",
    "final_at": "2026-11-07T09:00:08Z"
  }
}

ตรวจสอบลายเซ็น

ส่วนหัวมีเวลา Unix t และลายเซ็น v1 = HMAC-SHA256 ของสตริง "t.raw_body" ด้วยความลับ webhook ของคุณ ในรูปเลขฐานสิบหก คำนวณจากเนื้อหาดิบก่อนแยกวิเคราะห์ JSON เทียบแบบเวลาคงที่ และปฏิเสธเหตุการณ์ที่เก่ากว่าห้านาที

import crypto from "node:crypto";

export function verify(rawBody, header, secret) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || "");
  if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
  const want = crypto.createHmac("sha256", secret).update(m[1] + "." + rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(m[2]));
}

สถานะ

queuedรับแล้วและรอออกจากคิว
submittedส่งให้เครือข่ายปลายทางแล้ว
deliveredเครื่องผู้รับยืนยันแล้ว (สุดท้าย)
failedส่งไม่สำเร็จ คืนเงินแล้ว (สุดท้าย)
canceledส่วนหนึ่งของแคมเปญที่ตั้งเวลาไว้และถูกยกเลิกก่อนส่ง (สุดท้าย)

สถานะแคมเปญคือ scheduled, sending, complete หรือ canceled

ข้อผิดพลาด

ข้อผิดพลาดตอบกลับด้วยสถานะ HTTP และเนื้อหา JSON: { "error": { "code": "insufficient_balance", "message": "..." } } จะไม่มีการหักเงินเมื่อคำขอตอบกลับเป็นข้อผิดพลาด

HTTPรหัสความหมาย
400invalid_requestฟิลด์หายไปหรือไม่ถูกต้อง ข้อความจะบอกว่าฟิลด์ใด
400invalid_jsonเนื้อหาไม่ใช่ JSON
400no_valid_numbersไม่สามารถอ่านหมายเลขใดได้เลย
401unauthorizedไม่มีคีย์ คีย์รูปแบบผิด หรือคีย์ถูกแทนที่แล้ว
402insufficient_balanceยอดเงินไม่พอสำหรับค่าใช้จ่าย เติมเงินแล้วส่งอีกครั้ง
404not_foundไม่รู้จัก ID หรือเอ็นด์พอยต์
409not_scheduledยกเลิกได้เฉพาะแคมเปญที่ตั้งเวลาไว้และยังไม่เริ่ม
413too_many_recipientsเกิน 10,000 หมายเลขในหนึ่งคำขอ
429rate_limitedเกิน 300 คำขอในหนึ่งนาที
500server_errorลองส่งคำขอใหม่ จะไม่มีการหักเงิน

รับคีย์ API ในคอนโซล

สร้างบัญชี เติมเงินครั้งแรก แล้วสร้างคีย์ใต้ API คำขอแรกของคุณส่งได้ในอีกหนึ่งนาที

สร้างบัญชี
เอกสารอ้างอิง API สำหรับ SMS จำนวนมาก: เอ็นด์พอยต์ REST และ Webhook | BulkSMSOnline