Send bulk SMS and RCS across India without DLT — one REST endpoint, personalization built in, delivery reports on demand.
01
The CheapBulkSMS API lets you send SMS and RCS messages to any Indian mobile number programmatically — no DLT registration, flat ₹0.80 per SMS and ₹1.50 per RCS message. All requests are JSON over HTTPS.
Base URL https://cheap-bulk-sms-india.com Endpoints POST /api/v1/sms Send SMS or RCS POST /api/v1/reports Fetch delivery statuses
02
Create an API token from your dashboard under Dashboard → API. Tokens are shown once at creation — store them securely and never expose them in client-side code. Pass the token on every request in the x-api-key header (or as Authorization: Bearer).
x-api-key: cbs_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Requests without a valid token return 401 Unauthorized. Revoking a token in the dashboard disables it immediately.
03
Send one message to up to thousands of numbers in a single call. Numbers can be 10-digit Indian mobiles (we prefix +91) or include the country code; duplicates are removed automatically.
| Field | Type | Description |
|---|---|---|
| numbers | string | string[] | Comma/space/newline-separated numbers, or an array. Required unless recipients is used. |
| message | string | Message text. Required with numbers. |
| senderId | string (optional) | 6-char sender ID. A default is used when omitted. |
| type | "sms" | "rcs" | Channel. Defaults to "sms". |
curl -X POST https://cheap-bulk-sms-india.com/api/v1/sms \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_TOKEN" \
-d '{
"numbers": "9876543210, 9123456780",
"message": "FLAT 50% OFF this weekend at MyStore. Shop now: https://mystore.in",
"senderId": "MYSTOR"
}'Node.js
const res = await fetch("https://cheap-bulk-sms-india.com/api/v1/sms", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.CBS_API_KEY,
},
body: JSON.stringify({
numbers: ["9876543210", "9123456780"],
message: "Your order #4821 has shipped!",
}),
});
const data = await res.json();
console.log(data.sent, data.messageIds);Python
import requests
resp = requests.post(
"https://cheap-bulk-sms-india.com/api/v1/sms",
headers={"x-api-key": "YOUR_TOKEN"},
json={
"numbers": "9876543210,9123456780",
"message": "Your OTP is 482910. Valid for 10 minutes.",
},
)
print(resp.json())Success response
{
"status": "success",
"total": 2,
"sent": 2,
"failed": 0,
"messageIds": ["2412170930123456", "2412170930123457"],
"failures": [],
"invalidNumbers": []
}Keep the messageIds — you'll use them to query delivery reports.
04
To send a different message to each number — names, order IDs, amounts, links — pass a recipients array instead of numbers. Each entry carries its own final message text, so you control the templating in your own system.
curl -X POST https://cheap-bulk-sms-india.com/api/v1/sms \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_TOKEN" \
-d '{
"recipients": [
{ "phone": "9876543210", "message": "Hi Rahul, your EMI of Rs 4,500 is due on 20 Oct." },
{ "phone": "9123456780", "message": "Hi Priya, your EMI of Rs 7,200 is due on 22 Oct." }
],
"senderId": "MYFINC"
}'05
RCS delivers rich, branded messages on supported Android devices at ₹1.50 per message. Use the same endpoint with "type": "rcs". Recipients whose handset can't receive RCS are returned in failures — resend those over SMS for full coverage.
curl -X POST https://cheap-bulk-sms-india.com/api/v1/sms \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_TOKEN" \
-d '{
"numbers": "9876543210,9123456780",
"message": "Diwali Mega Sale is live! Up to 60% off storewide.",
"type": "rcs"
}'{
"status": "success",
"total": 2,
"sent": 1,
"failed": 1,
"messageIds": ["2412170931987654"],
"failures": [
{ "phone": "919123456780", "reason": "RCS not accepted (status -42)" }
],
"invalidNumbers": []
}SMS fallback pattern: collect the phones from failures and POST them again with "type": "sms".
06
Query the delivery status of previously sent messages using the messageIds returned by the send call. Up to 5,000 IDs per request.
curl -X POST https://cheap-bulk-sms-india.com/api/v1/reports \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_TOKEN" \
-d '{ "messageIds": ["2412170930123456", "2412170930123457"] }'{
"status": "success",
"statuses": {
"2412170930123456": "delivered",
"2412170930123457": "pending"
}
}| Field | Type | Description |
|---|---|---|
| delivered | status | Handset confirmed receipt. |
| pending | status | Accepted by operators, delivery receipt not in yet — poll again in 1–2 minutes. |
| failed | status | Could not be delivered (switched off, invalid, DND on some routes). |
07
Billing is per segment. Plain English (GSM-7) messages fit 160 characters in one segment, 153 per segment when longer. Unicode messages — Hindi, Marathi, emoji, the ₹ symbol — fit 70 characters per single segment, 67 when longer.
| Field | Type | Description |
|---|---|---|
| GSM-7 (English) | 160 / 153 | 1 segment up to 160 chars; 153 per segment after that. |
| Unicode (हिंदी etc.) | 70 / 67 | 1 segment up to 70 chars; 67 per segment after that. |
A 200-character English message = 2 segments = 2 × ₹0.80. Keep OTPs and alerts under 160 GSM characters for single-segment cost.
08
| Field | Type | Description |
|---|---|---|
| 401 | HTTP | Missing or invalid API token. |
| 400 | HTTP | Validation error — empty message, no valid numbers, malformed JSON. Details in the error field. |
| 429 | HTTP | Rate limited (trial endpoint). |
| 502 | HTTP | Upstream gateway rejected the request — retry with backoff. |
| failures[] | body | Per-number rejections inside an otherwise successful call: {phone, reason}. |
| invalidNumbers[] | body | Inputs that are not valid Indian mobile numbers; they are skipped, not billed. |
{
"status": "error",
"error": "Invalid or missing API key. Pass it as the x-api-key header."
}09
| Field | Type | Description |
|---|---|---|
| Numbers per call | 10,000 | Send larger lists in multiple calls; duplicates are dropped per call. |
| Report IDs per call | 5,000 | Chunk delivery lookups. |
| Minimum account order | 5,000 SMS | ₹4,000 at ₹0.80/SMS; credits never expire. |
messageIds with your own order/user records so delivery reports map back cleanly.Ready to integrate?
Create your token in the dashboard and send your first message in under a minute.
Get your API token₹0.80/SMS · No DLT
₹50 free credit on signup