দ্রুত শুরু
- 1. একটি কী তৈরি করুন। ওয়ার্কস্পেসে API এবং ওয়েবহুকস খুলুন। আপনার প্রথম ক্রেডিট টপ-আপের পর কীগুলি খুলবে; প্রতিটি কী একবার দেখানো হয়, তাই এটি কপি করুন বা একটি টেক্সট ফাইল হিসাবে সংরক্ষণ করুন।
- 2. খরচ পরীক্ষা করুন। প্রাপক, সেগমেন্ট এবং মোট খরচ দেখতে
/costsএ একই বডি POST করুন (পাঠানো ছাড়াই)। - 3. পাঠান। এটি
/sendsএ POST করুন। উত্তরে পাঠানোর আইডি থাকে; বার্তাগুলি সাথে সাথে বাsend_atএ পাঠানো হয়।
curl https://sendsmsonline.cc/api/v1/sends \
-H "Authorization: Bearer $SSO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "recipients": [ { "to": "+447700900461", "fields": { "first_name": "Tom" } }, { "to": "+12015550142", "fields": { "first_name": "Ava" } } ], "text": "Hi {{first_name}}, your table is ready at 7:30.", "name": "Friday bookings", "client_ref": "bookings-1107" }'const res = await fetch("https://sendsmsonline.cc/api/v1/sends", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SSO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
recipients: [{ to: "+447700900461", fields: { first_name: "Tom" } }],
text: "Hi {{first_name}}, your table is ready at 7:30.",
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data.send.id, data.send.cost_usd);import os, requests
r = requests.post(
"https://sendsmsonline.cc/api/v1/sends",
headers={"Authorization": f"Bearer {os.environ['SSO_API_KEY']}"},
json={
"recipients": [{"to": "+447700900461", "fields": {"first_name": "Tom"}}],
"text": "Hi {{first_name}}, your table is ready at 7:30.",
},
timeout=30,
)
data = r.json()
if r.status_code >= 400:
raise RuntimeError(data["error"]["message"])
print(data["send"]["id"], data["send"]["cost_usd"])<?php
$ch = curl_init("https://sendsmsonline.cc/api/v1/sends");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("SSO_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"recipients" => [["to" => "+447700900461", "fields" => ["first_name" => "Tom"]]],
"text" => "Hi {{first_name}}, your table is ready at 7:30.",
]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data["send"]["id"] ?? $data["error"]["message"];প্রমাণীকরণ
Authorization হেডারে আপনার কী পাঠান: Authorization: Bearer sso_live_...। কীগুলি 49 অক্ষরের এবং sso_live_ দিয়ে শুরু হয়। প্রতি অ্যাকাউন্টে সর্বোচ্চ 5 টি কী; ওয়ার্কস্পেসে একটি বাতিল করুন এবং এটি সাথে সাথে কাজ বন্ধ করে দেবে। মূল্য তালিকা পাবলিক এবং কোন কী প্রয়োজন নেই।
ত্রুটিসমূহ
ত্রুটিগুলি HTTP স্ট্যাটাস কোড এবং একটি স্থায়ী কোড সহ একটি JSON বডি ব্যবহার করে যা আপনি একজন ব্যক্তিকে দেখাতে পারেন। একটি অনুরোধ ব্যর্থ হলে কোন কিছু চার্জ করা হয় না।
HTTP/1.1 402 Payment Required
{ "error": { "code": "insufficient_credit", "message": "Short by $3.20. Add funds to send.", "total": "8.62480", "credit": "5.42000" } }| ফিল্ড | টাইপ | অর্থ |
|---|---|---|
| 400 | invalid_json, text_missing, recipients_missing, too_many_recipients, too_many_segments, schedule_range, bad_send_at | অনুরোধে একটি পরিবর্তন প্রয়োজন। |
| 401 | unauthorized | হারানো, ভুল বা বাতিল করা কী। |
| 402 | insufficient_credit | মোট খরচের জন্য পর্যাপ্ত ব্যালেন্স নেই। |
| 404 | not_found | এমন কোন পাঠানো, বার্তা, দেশ বা এন্ডপয়েন্ট নেই। |
| 409 | not_cancelable | পাঠানো ইতিমধ্যে শুরু হয়েছে। |
| 429 | rate_limited | এক মিনিটে 240 এর বেশি অনুরোধ। |
সীমাবদ্ধতা
- প্রতি কী প্রতি মিনিটে 240 অনুরোধ, X-RateLimit-Limit, X-RateLimit-Remaining এবং X-RateLimit-Reset (unix সেকেন্ড) এ দেখানো হয়েছে।
- প্রতি অনুরোধে 5,000 নম্বর, প্রতি টেক্সটে 2,000 অক্ষর, প্রতি বার্তায় 10 সেগমেন্ট।
- প্রতি অ্যাকাউন্টে প্রতি মিনিটে 300 পর্যন্ত বার্তা পাঠানো হয়।
- send_at 10 মিনিট থেকে 30 দিন আগে।
দাম
GET/api/v1/prices
GET/api/v1/prices/{country}
প্রতিটি দেশের জন্য প্রতি বার্তার (এক সেগমেন্ট) মূল্য, 5 দশমিক সহ USD এ। কী প্রয়োজন নেই।
{ "price": { "country": "GB", "name": "United Kingdom", "dial_code": "+44", "price_usd": "0.00868" }, "updated": "2026-11-07" }অ্যাকাউন্ট ব্যালেন্স
GET/api/v1/account
{ "account": "SO8K2M4Q7X9TBA", "credit_usd": "41.27660", "currency": "USD" }খরচ অনুমান করুন
POST/api/v1/costs
একটি পাঠানোর মতো একই বডি নেয় এবং এটি কত খরচ হবে তা ফেরত দেয়, পাঠানো বা চার্জ ছাড়াই। প্রতিটি প্রাপকের নিজস্ব মার্জ করা টেক্সট তার সেগমেন্ট নির্ধারণ করে, তাই মোটটি সঠিক।
{
"recipients": 2, "segments_min": 1, "segments_max": 1, "encoding": "gsm7", "messages_billed": 2,
"total_usd": "0.01426", "credit_usd": "41.27660", "enough_credit": true,
"countries": [ { "country": "GB", "recipients": 1, "price_usd": "0.00868", "subtotal_usd": "0.00868" },
{ "country": "US", "recipients": 1, "price_usd": "0.00558", "subtotal_usd": "0.00558" } ],
"dropped": [], "too_long": null
}একটি পাঠান তৈরি করুন
POST/api/v1/sends
এক বা একাধিক নম্বরে একটি টেক্সট। পুরো পাঠানোর জন্য ক্রেডিট নেওয়া হয় যখন এটি গ্রহণ করা হয়; ব্যর্থ বার্তাগুলি একে একে ফেরত দেওয়া হয়।
| ফিল্ড | টাইপ | অর্থ |
|---|---|---|
| to | string or array | আন্তর্জাতিক ফরম্যাটে নম্বর (+447700900461)। এটি বা প্রাপকদের ব্যবহার করুন। |
| recipients | array | to এবং fields সহ অবজেক্ট, মার্জ ফিল্ডের জন্য: { "to": "+1...", "fields": { "first_name": "Ava" } }। |
| text | string | বার্তা, 2,000 অক্ষর পর্যন্ত। {{field}} প্রতিটি প্রাপকের জন্য প্রতিস্থাপিত হয়; অনুপস্থিত মানগুলি খালি হয়ে যায়। |
| send_at | string | অফসেট বা Z সহ ঐচ্ছিক ISO 8601 সময়। এটি ছাড়া পাঠানো অবিলম্বে শুরু হয়। |
| name | string | ওয়ার্কস্পেসে দেখানো ঐচ্ছিক লেবেল (80 অক্ষর)। |
| client_ref | string | ওয়েবহুকগুলিতে ফেরত দেওয়া ঐচ্ছিক রেফারেন্স (64 অক্ষর)। |
| opt_out | boolean | সেটিংসে সংরক্ষিত অপ্ট-আউট লাইনটি টেক্সটের শেষে যোগ করে। |
| default_country | string | দেশ কোড ছাড়া লেখা নম্বরগুলির জন্য ব্যবহৃত ISO কোড। |
HTTP/1.1 201 Created
{
"send": { "id": "CA7Q29XMAB4DFK", "status": "queued", "source": "api", "recipients": 2, "segments_max": 1,
"encoding": "gsm7", "cost_usd": "0.01426", "refunded_usd": "0.00000", "client_ref": "bookings-1107",
"send_at": null, "created_at": "2026-11-07T10:12:03.120Z", "started_at": null, "finished_at": null },
"dropped": [ { "value": "+4412", "code": "too_short", "message": "Too short" } ]
}যে নম্বরগুলি পাঠানো যায় না সেগুলি dropped তে তালিকাভুক্ত করা হয় এবং কখনও চার্জ করা হয় না। কোড: no_country_code, too_short, too_long, not_a_number, wrong_length, not_covered, duplicate এবং suppressed (আপনার ডু-নট-সেন্ড তালিকায়)।
পাঠানো গুলি পান বা তালিকাভুক্ত করুন
GET/api/v1/sends/{id}
GET/api/v1/sends?limit=25&before={id}
একটি একক পাঠানোতে বার্তার অবস্থা অনুযায়ী counts অন্তর্ভুক্ত থাকে। তালিকাগুলি নতুনতম প্রথম; পরবর্তী পৃষ্ঠার জন্য next_before কে before হিসাবে পাস করুন। ওয়ার্কস্পেস থেকে পাঠানোও এখানে দেখা যায়, source: "web" সহ।
বার্তা
GET/api/v1/sends/{id}/messages?status=failed&limit=100
GET/api/v1/messages/{id}
{ "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
"segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
"created_at": "2026-11-07T10:12:03.120Z", "sent_at": "2026-11-07T10:12:04.010Z", "done_at": "2026-11-07T10:12:09.400Z" } }একটি পাঠান বাতিল করুন
POST/api/v1/sends/{id}/cancel
শুধুমাত্র নির্ধারিত পাঠানোগুলি যা শুরু হয়নি তা বাতিল করা যেতে পারে। সম্পূর্ণ খরচ আপনার ক্রেডিটে ফেরত দেওয়া হয় এবং উত্তরটি refunded_usd অন্তর্ভুক্ত করে।
ওয়েবহুকস
ওয়ার্কস্পেসে একটি https URL সেট করুন (API এবং ওয়েবহুক)। আমরা একটি ইভেন্ট POST করি যখন একটি বার্তা ডেলিভারি হয় বা ব্যর্থ হয়, API এবং ওয়ার্কস্পেস উভয় থেকে পাঠানোর জন্য। 10 সেকেন্ডের মধ্যে যেকোনো 2xx স্ট্যাটাস দিয়ে উত্তর দিন। ব্যর্থ ডেলিভারিগুলি সর্বমোট 7 বার পুনরায় চেষ্টা করা হয়: অবিলম্বে, তারপর 1 মিনিট, 5 মিনিট, 30 মিনিট, 1 ঘন্টা, 2 ঘন্টা এবং 3 ঘন্টা পরে। ওয়ার্কস্পেস প্রতিটি প্রচেষ্টা তার অবস্থা এবং উত্তর সহ দেখায়।
POST https://your-server.example/sms-events
X-SSO-Event: message.delivered
X-SSO-Delivery: evt_5a0c9e31d2b7f4a68c
X-SSO-Timestamp: 1794132729
X-SSO-Signature: sha256=8f1c...e42a
{ "id": "evt_5a0c9e31d2b7f4a68c", "event": "message.delivered", "created": "2026-11-07T10:12:09.000Z",
"data": { "message": { "id": "MS3D8RW0K2QJ7N", "send_id": "CA7Q29XMAB4DFK", "to": "+447700900461", "country": "GB",
"segments": 1, "price_usd": "0.00868", "status": "delivered", "reason": null, "reason_text": null,
"client_ref": "bookings-1107", "created_at": "...", "sent_at": "...", "done_at": "..." } } }স্বাক্ষরটি HMAC-SHA256 এর timestamp + "." + raw body আপনার সাইনিং সিক্রেট সহ (এটি sso_whk_ দিয়ে শুরু হয়)। পার্স করার আগে কাঁচা বডিতে এটি পরীক্ষা করুন, 5 মিনিটের বেশি পুরানো টাইমস্ট্যাম্পগুলি প্রত্যাখ্যান করুন, এবং পুনরাবৃত্তি উপেক্ষা করতে ডেলিভারি আইডি ব্যবহার করুন।
import crypto from "node:crypto";
// rawBody: the request body exactly as received (a string), before JSON.parse
export function verify(rawBody, headers, secret) {
const ts = headers["x-sso-timestamp"];
const sig = headers["x-sso-signature"] || "";
const want = "sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
return fresh && sig.length === want.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
ts = headers.get("X-SSO-Timestamp", "")
sig = headers.get("X-SSO-Signature", "")
mac = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256)
want = "sha256=" + mac.hexdigest()
fresh = ts.isdigit() and abs(time.time() - int(ts)) < 300
return fresh and hmac.compare_digest(sig, want)<?php
function verify(string $rawBody, string $ts, string $sig, string $secret): bool {
$want = "sha256=" . hash_hmac("sha256", $ts . "." . $rawBody, $secret);
return ctype_digit($ts) && abs(time() - (int)$ts) < 300 && hash_equals($want, $sig);
}ইভেন্ট: message.delivered, message.failed, এবং test সেন্ড টেস্ট ইভেন্ট বাটন থেকে।
স্ট্যাটাস এবং কারণসমূহ
| ফিল্ড | টাইপ | অর্থ |
|---|---|---|
| queued | status | আমাদের কিউ থেকে বের হওয়ার জন্য অপেক্ষা করছে। |
| sent | status | নেটওয়ার্কে হস্তান্তর করা হয়েছে, ডেলিভারি রিপোর্টের জন্য অপেক্ষা করা হচ্ছে। বেশিরভাগ রিপোর্ট কয়েক মিনিটের মধ্যে আসে; কিছু নেটওয়ার্ক 24 ঘন্টা পর্যন্ত সময় নিতে পারে। |
| delivered | status | নেটওয়ার্ক নিশ্চিত করেছে যে ফোনটি এটি পেয়েছে। |
| failed | status | ডেলিভারি করা হয়নি। মূল্য আপনার ব্যালেন্সে ফেরত দেওয়া হয়েছে। |
| canceled | status | আপনি বাতিল করেছেন বলে পাঠানো হয়নি। ফেরত দেওয়া হয়েছে। |
ব্যর্থতার কারণ (the reason field):
| ফিল্ড | টাইপ | অর্থ |
|---|---|---|
| network_error | reason | নেটওয়ার্ক ত্রুটি |
| absent | reason | ফোন বন্ধ বা কভারেজের বাইরে |
| not_in_service | reason | নম্বর সার্ভিসে নেই |
| blocked | reason | নেটওয়ার্ক বা প্রাপক দ্বারা ব্লক করা হয়েছে |
| landline | reason | ল্যান্ডলাইন বা এমন নম্বর যা এসএমএস গ্রহণ করতে পারে না |
| content_filter | reason | নেটওয়ার্কের কন্টেন্ট ফিল্টার দ্বারা প্রত্যাখ্যাত |
| expired | reason | মেয়াদোত্তীর্ণ: নেটওয়ার্কের সময়সীমার আগে কোনো রিপোর্ট নেই |
| canceled | reason | পাঠানোর আগে বাতিল করা হয়েছে |
| unknown | reason | অজানা নেটওয়ার্ক প্রতিক্রিয়া |
সার্ভিস চেকগুলি status page এ এবং API পরিবর্তনগুলি changelog এ রয়েছে।