เริ่มต้นอย่างรวดเร็ว
- สร้างบัญชีและเติมเงินในคอนโซล
- เปิด API keys และสร้างคีย์ คีย์สามารถสร้างได้หลังจากเติมเงินครั้งแรกเสร็จสิ้น คีย์จะแสดงเพียงครั้งเดียว; จัดเก็บเป็นความลับ
- ส่งคำขอ POST ไปที่
/smsพร้อมหมายเลขและข้อความ อ่านรหัสแคมเปญที่ส่งกลับมา จากนั้นติดตามการจัดส่งในคอนโซลหรือผ่านเว็บฮุค
การยืนยันตัวตน
ทุกคำขอยกเว้นรายการอัตราสาธารณะต้องมีคีย์ในส่วนหัว Authorization คีย์เริ่มต้นด้วย sbk_live_ คีย์ใหม่จะแทนที่คีย์เก่าทันที
Authorization: Bearer sbk_live_YOUR_KEYส่ง SMS
POST/sms
สร้างแคมเปญ หักเงินจากยอดเงิน และเข้าคิวทุกข้อความ หมายเลขจะถูกทำความสะอาดและกำจัดซ้ำ; หมายเลขที่ไม่สามารถใช้ได้จะถูกส่งกลับใน dropped พร้อมเหตุผลและไม่ถูกคิดเงิน
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
toจำเป็น | สตริงหรืออาร์เรย์ | หมายเลขเดียวหรืออาร์เรย์สูงสุด 10,000 หมายเลขในรูปแบบสากล เช่น "+447700900461" |
textจำเป็น | สตริง | ข้อความ สูงสุด 10 ส่วน ข้อความ GSM-7 ใช้ได้ 160 ตัวอักษรต่อส่วน UCS-2 ใช้ได้ 70 ตัวอักษร |
schedule_atไม่จำเป็น | สตริง | เวลา ISO 8601 จาก 5 นาทีถึง 60 วันข้างหน้า ไม่ระบุเพื่อส่งทันที |
client_refไม่จำเป็น | สตริง | อ้างอิงของคุณเอง สูงสุด 64 ตัวอักษร a-z A-Z 0-9 _ . : -, ส่งกลับในรายงานและเว็บฮุค |
opt_outไม่จำเป็น | บูลีน | true เพิ่มบรรทัดเลิกรับในตั้งค่าบัญชีของคุณ |
curl -X POST https://sendbulksms.cc/api/v1/sms \
-H "Authorization: Bearer sbk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["+447700900461", "+5511955550123"],
"text": "Hi, your order 4821 ships today.",
"client_ref": "orders-4821"
}'const res = await fetch("https://sendbulksms.cc/api/v1/sms", {
method: "POST",
headers: { Authorization: "Bearer " + process.env.SENDBULKSMS_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ to: ["+447700900461", "+5511955550123"], text: "Hi, your order 4821 ships today.", client_ref: "orders-4821" }),
});
const campaign = await res.json();
console.log(res.status, campaign.id, campaign.cost);import os, requests
r = requests.post(
"https://sendbulksms.cc/api/v1/sms",
headers={"Authorization": "Bearer " + os.environ["SENDBULKSMS_KEY"]},
json={"to": ["+447700900461", "+5511955550123"], "text": "Hi, your order 4821 ships today.", "client_ref": "orders-4821"},
timeout=30,
)
print(r.status_code, r.json()["id"])<?php
$ch = curl_init("https://sendbulksms.cc/api/v1/sms");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("SENDBULKSMS_KEY"), "Content-Type: application/json"],
CURLOPT_POSTFIELDS => json_encode(["to" => ["+447700900461", "+5511955550123"], "text" => "Hi, your order 4821 ships today.", "client_ref" => "orders-4821"]),
]);
$campaign = json_decode(curl_exec($ch), true);
echo $campaign["id"];ตอบกลับ: แคมเปญพร้อมค่าใช้จ่ายและข้อความ 1,000 ข้อความแรก ดึงข้อมูลเพิ่มเติมด้วยข้อความแคมเปญ
HTTP/1.1 201 Created
{
"id": "CP-7KQ2-M9XA-4HTD",
"status": "sending",
"source": "api",
"recipients": 2,
"segments": 1,
"encoding": "GSM-7",
"cost": "0.01078",
"refunded": "0.00000",
"client_ref": "orders-4821",
"scheduled_at": null,
"created_at": "2026-11-07T10:32:04.118Z",
"done_at": null,
"counts": { "queued": 2, "sent": 0, "delivered": 0, "failed": 0, "canceled": 0 },
"dropped": [],
"balance": "248.30422",
"messages": [
{ "id": "SM-2RBW-8MZN-QF6K", "campaign_id": "CP-7KQ2-M9XA-4HTD", "to": "+447700900461", "country": "GB", "parts": 1, "price": "0.00819", "status": "queued", "error": null, "created_at": "2026-11-07T10:32:04.118Z", "sent_at": null, "done_at": null }
]
}ประมาณการการส่ง
POST/estimate
ใช้เนื้อหาเดียวกันกับ /sms และส่งกลับผู้รับ ส่วน การเข้ารหัส ค่าใช้จ่ายทั้งหมด และค่าใช้จ่ายต่อประเทศโดยไม่คิดเงินหรือส่งอะไร
{ "recipients": 2, "dropped": [], "segments": 1, "encoding": "GSM-7", "cost": "0.01078", "balance": "248.31500",
"countries": [ { "country": "GB", "recipients": 1, "cost": "0.00819" }, { "country": "BR", "recipients": 1, "cost": "0.00259" } ] }สถานะข้อความ
GET/sms/{message_id}
ส่งกลับหนึ่งข้อความ: หมายเลข ประเทศ ส่วน ราคา สถานะ ข้อผิดพลาดสำหรับข้อความที่ล้มเหลวและเวลาของแต่ละขั้นตอน
แคมเปญ
GET/campaigns/{campaign_id}
แคมเปญพร้อมค่าใช้จ่าย การคืนเงิน และจำนวนข้อความต่อสถานะ
GET/campaigns/{campaign_id}/messages?offset=0&limit=100
ข้อความตามลำดับที่เข้าคิว สูงสุด 1,000 ข้อความต่อหน้า
POST/campaigns/{campaign_id}/cancel
ยกเลิกแคมเปญที่กำหนดเวลาซึ่งยังไม่เริ่มและคืนเงินเต็มจำนวนไปยังยอดเงิน
ยอดเงินและอัตราค่าใช้จ่าย
GET/balance
{ "balance": "248.31500", "currency": "USD" }GET/rates
สาธารณะ ไม่ต้องใช้คีย์ ทุกประเทศพร้อมรหัสโทรและราคาต่อส่วน /rates/GB ส่งกลับหนึ่งประเทศ
{ "updated": "2026-11-07", "rates": [ { "country": "GB", "name": "United Kingdom", "calling_code": "+44", "price": "0.00819", "currency": "USD", "unit": "SMS segment" } ] }เว็บฮุคการจัดส่ง
ตั้งค่า URL เว็บฮุคในคอนโซลภายใต้ API keys เมื่อข้อความถึงสถานะสุดท้าย (จัดส่งหรือล้มเหลว) เราจะ POST รายงานไปที่ URL ตอบกลับด้วยสถานะ 2xx ใดๆ ภายใน 8 วินาที; ไม่เช่นนั้นจะลองอีกครั้งสูงสุด 8 ครั้งในประมาณ 11 ชั่วโมง ใช้ id เพื่อละเว้นรายงานที่คุณประมวลผลแล้ว
POST https://your-server.example/sms-status
Content-Type: application/json
X-SendBulkSMS-Signature: t=1794047524,v1=5f0c3b9e...
{
"event": "message.status",
"id": "evt_8c1d2e4f6a7b9c0d1e2f",
"created_at": "2026-11-07T10:32:09.004Z",
"data": {
"message_id": "SM-2RBW-8MZN-QF6K",
"campaign_id": "CP-7KQ2-M9XA-4HTD",
"to": "+447700900461",
"country": "GB",
"status": "delivered",
"error": null,
"parts": 1,
"price": "0.00819",
"client_ref": "orders-4821",
"done_at": "2026-11-07T10:32:08.912Z"
}
}ตรวจสอบลายเซ็นก่อนเชื่อถือรายงาน: HMAC-SHA256 ของ t + "." + raw body ด้วยความลับเว็บฮุคของคุณ เปรียบเทียบในเวลาคงที่ และปฏิเสธเวลาที่เก่ากว่า 5 นาที
import { createHmac, timingSafeEqual } from "node:crypto";
// raw = the request body exactly as received (string), header = X-SendBulkSMS-Signature
export function verify(raw, 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 = Buffer.from(createHmac("sha256", secret).update(m[1] + "." + raw).digest("hex"));
const got = Buffer.from(m[2]);
return want.length === got.length && timingSafeEqual(want, got);
}import hmac, hashlib, re, time
def verify(raw: bytes, header: str, secret: str) -> bool:
m = re.fullmatch(r"t=(\d+),v1=([0-9a-f]{64})", header or "")
if not m or abs(time.time() - int(m.group(1))) > 300:
return False
want = hmac.new(secret.encode(), m.group(1).encode() + b"." + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(want, m.group(2))<?php
function verify(string $raw, string $header, string $secret): bool {
if (!preg_match('/^t=(\d+),v1=([0-9a-f]{64})$/', $header, $m) || abs(time() - (int)$m[1]) > 300) return false;
$want = hash_hmac('sha256', $m[1] . '.' . $raw, $secret);
return hash_equals($want, $m[2]);
}สถานะ
| สถานะ | ความหมาย |
|---|---|
queued | รับแล้วและคิดเงินแล้ว กำลังรอคิวในการส่ง |
sent | ส่งให้ผู้ให้บริการแล้ว กำลังรอรายงานการส่ง |
delivered | เครือข่ายยืนยันการส่งถึงมือถือแล้ว |
failed | ส่งไม่สำเร็จ เงินจะถูกคืนและแสดงสาเหตุใน error |
canceled | ส่วนหนึ่งของแคมเปญที่กำหนดเวลาถูกยกเลิกก่อนเริ่มส่ง เงินถูกคืน |
ข้อผิดพลาด
ข้อผิดพลาดใช้รหัสสถานะ HTTP และเนื้อหา JSON: { "error": { "code": "insufficient_balance", "message": "..." } } การร้องขอที่ส่งกลับข้อผิดพลาดจะไม่คิดเงินจากยอดเงิน
| HTTP | รหัส | เมื่อไหร่ |
|---|---|---|
| 400 | bad_requestไม่มีฟิลด์หรือฟิลด์ไม่ถูกต้อง ข้อความจะระบุว่าอันไหน | ไม่มีฟิลด์หรือฟิลด์ไม่ถูกต้อง ข้อความจะระบุว่าอันไหน |
| 400 | no_valid_numbersไม่มีหมายเลขใน "to" ที่สามารถใช้ได้ | ไม่มีหมายเลขใน "to" ที่สามารถใช้ได้ |
| 401 | unauthorizedไม่มี API key หรือไม่ถูกต้อง | ไม่มี API key หรือไม่ถูกต้อง |
| 402 | insufficient_balanceยอดเงินไม่พอสำหรับการส่ง ไม่มีการคิดเงิน | ยอดเงินไม่พอสำหรับการส่ง ไม่มีการคิดเงิน |
| 404 | not_foundแคมเปญ ข้อความหรือ endpoint ไม่มีในบัญชีของคุณ | แคมเปญ ข้อความหรือ endpoint ไม่มีในบัญชีของคุณ |
| 409 | not_scheduledเฉพาะแคมเปญที่กำหนดเวลาและยังไม่เริ่มส่งเท่านั้นที่ยกเลิกได้ | เฉพาะแคมเปญที่กำหนดเวลาและยังไม่เริ่มส่งเท่านั้นที่ยกเลิกได้ |
| 413 | too_many_recipientsมากกว่า 10,000 หมายเลขในหนึ่งคำขอ | มากกว่า 10,000 หมายเลขในหนึ่งคำขอ |
| 429 | rate_limitedมากกว่า 300 คำขอในหนึ่งนาทีสำหรับ key นี้ | มากกว่า 300 คำขอในหนึ่งนาทีสำหรับ key นี้ |
| 500 | server_errorลองอีกครั้ง ไม่มีการคิดเงินสำหรับคำขอที่ล้มเหลว | ลองอีกครั้ง ไม่มีการคิดเงินสำหรับคำขอที่ล้มเหลว |
ข้อจำกัด
- 300 คำขอต่อนาทีต่อ API key
- 10,000 หมายเลขต่อคำขอส่ง 10 ส่วนต่อข้อความ
- ข้อความจะถูกส่งสูงสุด 200 ข้อความต่อนาทีต่อคิว ตามลำดับที่รับมา
- กำหนดเวลาส่งล่วงหน้าได้ 5 นาทีถึง 60 วัน
- หมายเลขในรายชื่อไม่ส่งจะถูกข้ามและส่งกลับใน dropped พร้อมรหัส suppressed ไม่มีการคิดเงิน