Overview
The SMSLocal HTTP API lets you send DLT-compliant SMS, check delivery status, and manage your credit balance. It's a GET-based query-string API — simple enough to test from a browser, robust enough to power millions of messages a day.
Base URL
https://app.smslocal.in/apiProtocol
HTTPS · TLS 1.2+
Method
GET (query string)
Authentication
Every request must include your API key as the key query parameter. Get your key from Settings → API & Webhooks after you sign up. Keys are 32-character hex strings.
Environments
Every account has two sandbox credits to help you test the full round-trip — send → delivery report → credits — before you go live. Sandbox sends return a real message ID but don't deliver to the handset and don't consume paid credit. Use the exact same endpoint; SMSLocal routes the traffic based on the key you use.
Send SMS
Send a DLT-compliant SMS to one or more Indian mobile numbers. The response body is either a numeric message ID (success) or a numeric error code (see Error Codes table).
/smsapiParameters
| Parameter | Type | Description |
|---|---|---|
keyRequired | string | Your 32-character API key. Find it under Settings → API & Webhooks. Example: 0ec0e29706c4e213a2910b54147c1d5c |
routeRequired | integer | Delivery route. 1 for transactional (OTPs, service updates). 2 for promotional (marketing). Promotional can only send between 9:00 AM and 8:45 PM IST.Example: 1 |
senderRequired | string | 6-character DLT-registered sender ID (header). Must be approved under your Principal Entity. Example: ALERTS |
numberRequired | string | Comma-separated list of 10-digit Indian mobile numbers. No +91 prefix, no spaces. Example: 9876543210,9123456789 |
smsRequired | string | Message body, URL-encoded. Must exactly match an approved DLT template — including the position of {#var#} placeholders. Example: Your%20OTP%20is%20482913 |
templateidRequired | string | 19-digit DLT Content Template ID. Issued by your DLT platform after template approval. Example: 1207161234567890123 |
Request
curl "https://app.smslocal.in/api/smsapi" \
--get \
--data-urlencode "key=$SMSLOCAL_KEY" \
--data-urlencode "route=1" \
--data-urlencode "sender=ALERTS" \
--data-urlencode "number=9876543210" \
--data-urlencode "sms=Your OTP is 482913. Valid for 10 minutes." \
--data-urlencode "templateid=1207161234567890123"Response
Success returns a numeric message ID as plain text. Store it to poll delivery status later.
HTTP/1.1 200 OK
Content-Type: text/plain
1987654321 # Unique message ID — store this to fetch delivery status later.Delivery Reports
Fetch delivery status for a previously sent batch, given the message ID returned by Send SMS. For production workloads, prefer webhooks — they're faster and cost no extra credits.
/dlrapiParameters
| Parameter | Type | Description |
|---|---|---|
keyRequired | string | Your API key. |
messageidRequired | string | Unique message ID returned by the Send SMS endpoint. Example: 1987654321 |
Request
curl "https://app.smslocal.in/api/dlrapi" \
--get \
--data-urlencode "key=$SMSLOCAL_KEY" \
--data-urlencode "messageid=1987654321"Response
Returns a JSON array of [number, status, timestamp] tuples — one row per recipient. Possible status values: DELIVERED, FAILED, PENDING, EXPIRED.
HTTP/1.1 200 OK
Content-Type: application/json
[
["9876543210", "DELIVERED", "2026-04-20 14:21:08"],
["9123456789", "FAILED", "2026-04-20 14:21:12"],
["9000000001", "PENDING", "2026-04-20 14:21:04"]
]Check Credits
Get the currently available credit balance for a specific route. Useful for setting up low-balance alerts in your own monitoring stack.
/creditapiParameters
| Parameter | Type | Description |
|---|---|---|
keyRequired | string | Your API key. |
routeRequired | integer | 1 for transactional, 2 for promotional. Example: 1 |
Request
curl "https://app.smslocal.in/api/creditapi" \
--get \
--data-urlencode "key=$SMSLOCAL_KEY" \
--data-urlencode "route=1"Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"Route": "Transactional",
"Credits": "48215"
}Error Codes
When a request fails, the response body is a 3-digit error code (as plain text, or inside the JSON/XML envelope). Use this table to turn codes into helpful messages for your team.
| Code | Error | Meaning & fix |
|---|---|---|
101 | Invalid user | The API key is missing, malformed, or revoked. Fix: Re-copy the key from Settings → API & Webhooks. Keys are 32-character hex strings. |
102 | Invalid sender ID | The sender (header) is not registered on DLT under your Principal Entity. Fix: Register the 6-character header on your DLT platform and wait for it to sync (≈4 hours). |
103 | Invalid contact(s) | One or more destination numbers are not valid Indian mobile numbers. Fix: Numbers must be 10 digits, starting with 6/7/8/9. No +91 prefix, no spaces. |
104 | Invalid route | The route parameter is not 1 (transactional) or 2 (promotional). Fix: Use route=1 for OTPs and service updates, route=2 for marketing. |
105 | Invalid message | Message is empty, exceeds 1600 characters, or has disallowed characters. Fix: Url-encode the message. For Unicode (Hindi, Tamil, etc.) the limit is 70 chars per part. |
106 | Spam blocked | Message content matched a spam pattern flagged by the operator. Fix: Remove aggressive marketing language, unsolicited links, or prohibited keywords. |
107 | Promotional blocked | Recipient is on the DND (Do Not Disturb) list for this category. Fix: Expected for DND users on promotional route. Use transactional route for OTPs and alerts. |
108 | Low credits | You don't have enough credits on the selected route to send this batch. Fix: Top up in Settings → Billing, or switch to another route with available balance. |
109 | Promotional timing | Promotional sends are only allowed between 9:00 AM and 8:45 PM IST. Fix: Queue the send for tomorrow morning, or route as transactional if content qualifies. |
110 | Invalid DLT Template ID | The templateid does not match an approved template, or the content doesn't match the template body. Fix: Check the template exactly matches the registered body, including {#var#} variable positions. |
111 | No SMSC | No operator route is currently available for this combination of route + sender. Fix: Usually a transient upstream issue. Retry with exponential backoff. Check /status. |
Rate Limits
The API is tuned for bursty campaign traffic. Default limits comfortably support everything from small OTP workloads to multi-lakh broadcasts — but we'll raise them on request for verified accounts.
Requests / second
100
Per API key.
Recipients / call
5,000
For larger batches, chunk client-side.
DLR polls / second
20
Prefer webhooks for scale.
When you hit a limit, the API returns 429 and includes a Retry-Afterheader. Back off exponentially — don't hammer.
SDKs
You do not need an SDK. The three endpoints above are plain HTTP, so any HTTP client in Node.js, Python, PHP, Java, Go or any other language works. The code samples on this page are copy-paste ready.