বাল্ক SMS API v1
আপনার নিজের সফটওয়্যার থেকে বাল্ক এসএমএস পাঠানোর জন্য একটি ছোট REST API: JSON ইন এবং আউট, Bearer কী, কনসোলের মতো একই দাম এবং চেক, এবং ডেলিভারি রিপোর্টের জন্য সাইনড ওয়েবহুক। বেস URL https://smsbulk.cc/rest/v1
ওভারভিউ
প্রতি অনুরোধে 8,000 নম্বর পর্যন্ত পাঠান, প্রতিটির নিজস্ব মার্জ মান সহ, এবং API প্রতিটি প্রাপককে তাদের নিজস্ব মার্জ করা টেক্সটের সাথে দাম দেয়, ঠিক কনসোলের মতো। খরচ জানতে প্রথমে একই বডি সহ একটি কোট জিজ্ঞাসা করুন; একটি কোট দ্বারা কিছুই পাঠানো বা চার্জ করা হয় না। সময়গুলি ISO 8601 অনুযায়ী UTC, টাকা পাঁচ দশমিক সহ 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"
}'const res = await fetch("https://smsbulk.cc/rest/v1/send", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
recipients: [
{ to: "+14155550142", fields: { name: "Maria" } },
{ to: "+447400123456", fields: { name: "Tom" } },
],
text: "Hi {{name}}, your order ships today.",
client_ref: "order-batch-17",
}),
});
const data = await res.json();
console.log(res.status, data.campaign?.id, data.campaign?.cost);import requests
res = requests.post(
"https://smsbulk.cc/rest/v1/send",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"recipients": [
{"to": "+14155550142", "fields": {"name": "Maria"}},
{"to": "+447400123456", "fields": {"name": "Tom"}},
],
"text": "Hi {{name}}, your order ships today.",
"client_ref": "order-batch-17",
},
timeout=30,
)
data = res.json()
print(res.status_code, data.get("campaign", {}).get("id"))<?php
$body = json_encode([
"recipients" => [
["to" => "+14155550142", "fields" => ["name" => "Maria"]],
["to" => "+447400123456", "fields" => ["name" => "Tom"]],
],
"text" => "Hi {{name}}, your order ships today.",
"client_ref" => "order-batch-17",
]);
$ch = curl_init("https://smsbulk.cc/rest/v1/send");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_API_KEY", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => $body,
]);
$data = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $data["campaign"]["id"] ?? "", PHP_EOL;অনুমোদন
API এবং ওয়েবহুকের অধীনে কনসোলে একটি কী তৈরি করুন; আপনার প্রথম ক্রেডিটেড টপ-আপের পরে কীগুলি খুলবে। প্রতিটি অনুরোধে এটি Bearer টোকেন হিসাবে পাঠান। একটি কী একবার দেখানো হয়; আপনি 5 কী পর্যন্ত রাখতে পারেন এবং যেকোনোটি একবারে বাতিল করতে পারেন।
Authorization: Bearer smsb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxদর
পাবলিক, কোন কী প্রয়োজন নেই। প্রতিটি গন্তব্যের জন্য বা একটি 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 | string or string[] | একটি নম্বর বা তালিকা। + সহ আন্তর্জাতিক ফর্ম সবচেয়ে নিরাপদ; স্থানীয় নম্বরগুলির জন্য default_country প্রয়োজন। |
| recipients | object[] | to এর পরিবর্তে: { to, fields } এর একটি তালিকা যেখানে ফিল্ডগুলি {{name}} এর মতো মার্জ ফিল্ড পূরণ করে। |
| text | string | বার্তাটি, মার্জ করার পরে 2,000 অক্ষর এবং 10 সেগমেন্ট পর্যন্ত। |
| default_country | string | + ছাড়া লেখা নম্বরগুলির জন্য ব্যবহৃত ISO কোড, যেমন GB। সেটিংসে সংরক্ষিত ডিফল্টে ফিরে যায়। |
| opt_out | boolean | আপনার সংরক্ষিত অপ্ট-আউট শব্দগুলিকে শেষ লাইন হিসাবে যোগ করে (প্রথমে সেটিংসে সংরক্ষণ করুন)। |
{
"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 | string | শুরু করার ISO 8601 সময়, 5 মিনিট থেকে 90 দিন আগে। এখনই পাঠাতে বাদ দিন। |
| name | string | ক্যাম্পেইনের জন্য আপনার লেবেল, 80 অক্ষর পর্যন্ত। |
| client_ref | string | আপনার নিজের রেফারেন্স, 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
শুরু সময় পর্যন্ত কাজ করে। সম্পূর্ণ খরচ আপনার ক্রেডিটে একটি লেজার লাইনে ফেরত আসে এবং ক্যাম্পেইন স্ট্যাটাস বাতিল হয়ে যায়।
ওয়েবহুক
কনসোলে একটি এন্ডপয়েন্ট URL সেট করুন। আমরা message.delivered, message.failed এবং campaign.done এর জন্য JSON POST করি, প্লাস টেস্ট যখন আপনি Send test event টিপুন। প্রতিটি ইভেন্ট চারটি হেডার বহন করে, এবং 10 সেকেন্ডের মধ্যে যেকোনো 2xx উত্তর প্রাপ্ত হিসাবে গণনা করা হয়।
| ফিল্ড | টাইপ | অর্থ |
|---|---|---|
| Smsbulk-Event | হেডার | ইভেন্টের নাম, যেমন message.delivered। |
| Smsbulk-Delivery | হেডার | ডেলিভারি আইডি, একটি ইভেন্টের প্রতিটি পুনরায় চেষ্টায় একই। |
| Smsbulk-Timestamp | হেডার | ইউনিক্স সেকেন্ড যখন এই প্রচেষ্টা স্বাক্ষরিত হয়েছিল। |
| Smsbulk-Signature | হেডার | sha256= টাইমস্ট্যাম্পের 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));
}import base64, hashlib, hmac, time
def verify(raw: bytes, headers, secret: str) -> bool:
ts = headers.get("Smsbulk-Timestamp", "")
mac = hmac.new(secret.encode(), ts.encode() + b"\n" + raw, hashlib.sha256).digest()
want = "sha256=" + base64.b64encode(mac).decode()
fresh = abs(time.time() - int(ts or 0)) < 300
return fresh and hmac.compare_digest(want, headers.get("Smsbulk-Signature", ""))ত্রুটি ও সীমাবদ্ধতা
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_at | send_at 5 মিনিট থেকে 90 দিনের বাইরে, অথবা একটি বৈধ সময় নয়। | |
| 422 opt_out_unset | opt_out সত্য কিন্তু সেটিংসে কোনো অপ্ট-আউট টেক্সট সেভ করা নেই। | |
| 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 | কারণ | ল্যান্ডলাইন বা এমন নম্বর যা এসএমএস গ্রহণ করতে পারে না |
| content_filter | কারণ | নেটওয়ার্কের কন্টেন্ট ফিল্টার দ্বারা প্রত্যাখ্যাত |
| expired | কারণ | মেয়াদোত্তীর্ণ: নেটওয়ার্কের সময়সীমার আগে কোনো রিপোর্ট নেই |
| unknown | কারণ | অজানা নেটওয়ার্ক প্রতিক্রিয়া |
| canceled | কারণ | পাঠানোর আগে বাতিল করা হয়েছে |
API সম্পর্কে প্রশ্ন? কনসোলে একটি টিকেট খুলুন, বা FAQ পড়ুন।