Send bulk SMS in India via one HTTP API
One HTTP request puts an SMS on its way to any Indian mobile number. Pass your DLT template and principal entity ID, get a delivery receipt back on your webhook, and reconcile every message by ID. The same API sends transactional OTPs and promotional campaigns — you pick the route.
What you can build
Delivery you can see
Live in five minutes
DLT-ready by default
Send your first SMS in five minutes
Authentication is a bearer token. Every send is a single POST to /v1/sms with your sender header, the route, one or more E.164 numbers, the message body, and the two DLT identifiers India requires.
The response returns a request ID and a per-number message ID. Match that ID against the delivery receipt that arrives on your webhook moments later. There is no SDK to learn first — the JSON below is the whole contract.
Switch route from transactional to promotional to send marketing traffic. The DLT identifiers and sender header change with your registered templates; the call shape does not.
Errors return a non-2xx status with a stable error code — an invalid DLT template, an unregistered header, or a malformed number each carry their own code, so you branch on the code rather than parsing a message. Send an idempotency key with a batch and a retried request returns the original result instead of sending twice.
Each response includes your current rate-limit headers, so a client that reads them can pace itself and back off cleanly instead of being throttled. Limits are per API key and scale with your account.
A single SMS is 160 GSM-7 characters, or 70 when the body contains Unicode. Longer messages are split into concatenated parts, reassembled on the handset, and each part is charged and receipted as one SMS — the API returns the part count so billing is never a surprise.
Before you send live traffic, point a test API key at the same endpoints. Test sends are accepted and receipted without touching the operator network, so you can wire up your webhook handler and reconciliation end to end, then switch to a live key once your DLT header and templates are approved.
Delivery receipts move through a small set of states — submitted, sent, delivered, or failed — and each transition is posted to your webhook with the message ID and a timestamp. A failed receipt carries a reason code, so a number that is on DND, invalid, or out of credit is something you act on rather than guess at.
Two-way SMS works on a long code or a registered keyword on a short code. Inbound messages arrive on your webhook with the sender, the destination, and the body, which is enough to build opt-outs, keyword campaigns, and lightweight support flows without polling.
Throughput scales with your account rather than your code: the same single call that sends one message sends your whole list, and the response returns a message ID for each recipient so nothing is lost in a batch. Pace large jobs with the rate-limit headers and reconcile by request ID.
Campaigns can be queued for a future timestamp in IST and cancelled before they fire — a promotional send scheduled for business hours, a reminder for the morning of an appointment.
curl https://api.smsapi.in/v1/sms \
-H "Authorization: Bearer $SMSAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"sender": "SMSAPI",
"route": "transactional",
"numbers": ["+919876543210"],
"message": "Your OTP is 481920. Valid for 10 minutes.",
"dlt_template_id": "1707170000000000000",
"dlt_entity_id": "1101400000000000000"
}'
# Response
{
"request_id": "req_3f9a2b",
"messages": [
{ "message_id": "sms_9c81a0", "to": "+919876543210", "status": "submitted" }
]
}API request shapes are representative pending the white-label telco API spec (FLAGS_AND_ASSUMPTIONS.md).
What's included
Delivery receipts
Per-message DLRs pushed to your webhook, with retries and operator failover.
Transactional & promotional
Separate routes, each with its own sender header and DLT templates.
Header management
Register and manage 6-character sender headers (e.g. SMSAPI) per route.
Send your whole list in one call
Pass an array of numbers; we fan out and report the status of each one.
Hindi and regional scripts
Full Unicode (UCS-2) for Devanagari and other Indian scripts, 70 characters per part.
Per-message logs
Searchable logs and CSV exports, keyed by request and message ID.
Key auth and IP allowlist
Rotatable bearer API keys, with optional IP allowlisting.
Send now or later
Queue a campaign for a future timestamp in IST.
Built for Indian telecom compliance
SMS to Indian numbers is governed by TRAI and delivered through the DLT (Distributed Ledger Technology) framework. Before you can send, your business registers as a principal entity and receives a principal entity ID; each sender header and message template is registered separately and approved.
On every request you pass your principal entity ID and the DLT template ID that matches the message. We validate both against the registry before dispatch, so a mismatched template fails immediately rather than being silently scrubbed by the operator. Promotional traffic additionally respects DND (Do Not Disturb) preferences and time-of-day rules; transactional traffic is exempt.
Sender headers fall into categories that decide what you may send and when: transactional and service-implicit headers carry OTPs and account alerts around the clock, service-explicit headers carry consented service updates, and promotional headers carry marketing within permitted hours. Registering the right category up front avoids template rejections later.
Consent is your responsibility as the sender, and we keep the per-message records you need to evidence it. Our DLT guide covers principal entity registration, header approval, and template categories end to end.
Frequently asked
What is the DLT registration process for a new sender?
Register your business as a principal entity on a TRAI-accredited DLT portal, then register each sender header and message template. You receive a principal entity ID and a template ID for every message type. You pass both on each API request; we validate them before dispatch. Our DLT guide walks through each step.
Which SDK languages do you support?
The API is plain JSON over HTTPS, so any language with an HTTP client works. We publish quickstarts and helper libraries for cURL, Node.js, PHP, Python and Java. The request and response shapes are identical across all of them.
Can I send Unicode SMS in Hindi or regional languages?
Yes. Send the message body as UTF-8 and we encode it as Unicode (UCS-2) automatically. Unicode messages are 70 characters per part rather than 160, and long messages are concatenated. Devanagari and other Indian scripts are supported.
How do delivery webhooks work?
Each message returns a message ID synchronously. When the operator confirms the final state, we POST a delivery receipt to your configured webhook URL with that message ID and the status. Failed deliveries are retried, and you can also poll the message by ID.
What is the difference between the transactional and promotional routes?
Transactional traffic carries OTPs and service alerts to your customers at any hour, on a transactional sender header and template. Promotional traffic carries marketing content, is subject to DND scrubbing and time-of-day rules, and uses a promotional header. You select the route per request.
How is bulk SMS priced?
Pricing is per SMS, with GST shown separately, and rates step down by volume. See the pricing page for current per-message rates by route.
How do I verify a delivery webhook really came from you?
Each webhook POST is signed: a signature header is computed from the payload and your signing secret. Recompute the HMAC on your side and compare before trusting the event, then respond 2xx to acknowledge so retries stop. Reject anything that doesn't match.
Transparent pricing, with GST broken out
Per-SMS credit bundles, from 16.5p/SMS. Base price and 18% GST are shown separately, in rupees.