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
Official SDKs for Node.js, Python, PHP, Java, and Go are on the roadmap. Until then, the three endpoints above are simple enough that any HTTP client works — the code samples on this page are copy-paste ready.