त्वरित शुरुआत
- 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 (यूनिक्स सेकंड) में दिखाया गया है।
- प्रति अनुरोध 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 | वैकल्पिक ISO 8601 समय ऑफसेट या Z के साथ। इसके बिना संदेश तुरंत शुरू होता है। |
| 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": "..." } } }सिग्नेचर आपके साइनिंग सीक्रेट (यह sso_whk_ से शुरू होता है) के साथ timestamp + "." + raw body का HMAC-SHA256 है। पार्सिंग से पहले इसे रॉ बॉडी पर जांचें, 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, और Send test event बटन से test।
स्थितियाँ और कारण
| फ़ील्ड | प्रकार | अर्थ |
|---|---|---|
| queued | status | हमारी कतार छोड़ने की प्रतीक्षा कर रहा है। |
| sent | status | नेटवर्क को सौंप दिया गया है, डिलीवरी रिपोर्ट की प्रतीक्षा की जा रही है। अधिकांश रिपोर्ट कुछ मिनटों में आ जाती हैं; कुछ नेटवर्क को 24 घंटे तक का समय लग सकता है। |
| delivered | status | नेटवर्क ने पुष्टि की कि फोन ने इसे प्राप्त कर लिया है। |
| failed | status | डिलीवर नहीं हुआ। कीमत आपके बैलेंस में वापस कर दी गई है। |
| canceled | status | रद्द करने के कारण नहीं भेजा गया। वापस कर दिया गया। |
असफलता के कारण (reason फ़ील्ड):
| फ़ील्ड | प्रकार | अर्थ |
|---|---|---|
| network_error | reason | नेटवर्क त्रुटि |
| absent | reason | फोन बंद है या कवरेज से बाहर है |
| not_in_service | reason | नंबर सेवा में नहीं है |
| blocked | reason | नेटवर्क या प्राप्तकर्ता द्वारा ब्लॉक किया गया |
| landline | reason | लैंडलाइन या ऐसा नंबर जो SMS प्राप्त नहीं कर सकता |
| content_filter | reason | नेटवर्क के कंटेंट फ़िल्टर द्वारा अस्वीकृत |
| expired | reason | समय सीमा समाप्त: नेटवर्क की समय सीमा से पहले कोई रिपोर्ट नहीं |
| canceled | reason | भेजने से पहले रद्द किया गया |
| unknown | reason | अज्ञात नेटवर्क प्रतिक्रिया |
सेवा जांच status page पर है और API परिवर्तन changelog में हैं।