Features
One API for every message that matters
Verification codes, receipts and replies, sent from real local numbers and tracked end to end. Here is everything SMSRay does today, and what is coming next.
OTP verification
Two calls. Zero code storage.
We generate a 6-digit code, send it with your app name, keep only its hash and check what your user types. You never store or compare codes yourself.
- Valid for 5 minutes, 5 attempts
- 60 s resend cooldown per number
- At most 3 per 10 minutes per number
- Optional per-end-user IP limit
- Code hidden in logs and the dashboard
- Wrong code is a clean 200, not an error
# 1. Send a code (6 digits, valid 5 minutes)
curl https://api.smsray.in/api/sms/v1/sms/otp/send \
-H "x-api-key: $SMSRAY_API_KEY" -H "content-type: application/json" \
-d '{ "to": "9779801234567", "purpose": "login", "ip": "203.0.113.7" }'
# 2. Check what the user typed
curl https://api.smsray.in/api/sms/v1/sms/otp/verify \
-H "x-api-key: $SMSRAY_API_KEY" -H "content-type: application/json" \
-d '{ "to": "9779801234567", "purpose": "login", "code": "482913" }'curl https://api.smsray.in/api/sms/v1/sms/send \
-H "x-api-key: $SMSRAY_API_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: order-1042-shipped" \
-d '{ "to": "9779801234567", "text": "Your order #1042 has shipped." }'Transactional SMS
Receipts, reminders and alerts that land once
Order updates, payment confirmations, appointment reminders, delivery notices. One POST with a number and your text; we count segments, reserve the cost and start routing.
- Idempotency-Key: replays for 24 h return the original reply
- GSM-7: 160 chars, 153 per part after that
- Unicode and Nepali: 70 chars, 67 per part
- Up to 6 segments per message
- Per-key rate limit, 20 sends/s by default
- Check status any time with GET /sms/messages/:id
Two-way messaging
Customers can reply. You will hear it.
Because your messages come from a real mobile number, customers can answer them. Replies are matched to the most recent message you sent that number and pushed to your server.
Linked to the conversation
Each reply carries inReplyTo, the id of the message it answers, for replies within 72 hours.
In your dashboard inbox
Read replies next to the message log, and mark them read as your team works through them.
Conversation · 98XXXXXXXX
two-way{ "type": "message.inbound",
"from": "+9779801234567",
"text": "YES",
"inReplyTo": "2b1f6c1e-…" }Routing to 98XXXXXXXX · Ncell
On-net first · paced · quota-aware
SIM-pool routing
A router that picks the healthiest SIM, every time
Messages leave from a pool of company SIMs in managed Android phones. For each message the router scores every SIM and sends from the best one for that recipient.
- On-net first: Ncell to Ncell, NTC to NTC
- Paced at 30 sends per 30 minutes per SIM
- Daily quotas that reset on Nepal time
- Stale, failing or expired SIMs skipped
- One automatic retry on a different SIM
- Final failures refunded to your balance
Signed webhooks
Events you can trust, retried until they land
Set one webhook URL per API client and receive message.status and message.inbound events, each signed so you can prove it came from us.
- HMAC-SHA256 over timestamp and raw body
- Rejected outside a ±300 s window to stop replays
- Rotate secrets with zero downtime (two signatures)
- 8 attempts with growing backoff
- Never sent twice for the same status
- Delivery history kept for 7 days
x-lacspace-event: message.status x-lacspace-signature: t=1791612907, v1=5f0c9a…e41b user-agent: lacspace-sms-webhooks/1
Attempt schedule
- #1now
- #2+10 s
- #3+30 s
- #4+2 min
- #5+10 min
- #6+30 min
- #7+1 h
- #8+3 h
A 2xx stops the ladder. Permanent 4xx responses (except 408 and 429) stop after 3 attempts. Each attempt is re-signed with a fresh timestamp.
The dashboard
Everything about your messages, on one screen
Sign in with a one-time code to your phone or email. Search the log, send a test, manage keys and teammates, and watch delivery happen live.
Sent today
1,284
Delivered
1,251
Balance
NPR —
| To | Type | Message | Seg | Status |
|---|---|---|---|---|
| 98•••••213 | otp | (OTP hidden) | 1 | delivered |
| 97•••••480 | transactional | Your order #1042 has shipped. | 1 | sent |
| 98•••••771 | transactional | Payment of NPR 2,500 received. Thank you! | 1 | delivered |
| 98•••••034 | otp | (OTP hidden) | 1 | queued |
| 96•••••915 | promotional | Dashain offer: 20% off all plans this week… | 2 | delivered |
Messages
Every send with status, segments and route timeline
Inbound
Replies, linked to the message they answer
API clients
Keys, webhook URL and signing secret
Members
Invite teammates by phone, set roles
Security
Your signed-in sessions, sign out any device
Workspaces and team
Bring your team. Keep control.
Every account gets its own workspace. Invite teammates by phone number and decide who can change what.
| What you can do | Member | Owner |
|---|---|---|
| Read messages, replies, stats and members | ||
| Send from the dashboard | ||
| Manage your own profile and sessions | ||
| Create API clients, rotate keys, set webhooks | — | |
| Invite, promote and remove members | — | |
| Rename the workspace | — |
Invite by phone
Add a teammate by phone number. They join your workspace the first time they sign in. A workspace always keeps at least one owner.
Activation
New workspaces start pending. You can set up keys and webhooks straight away; sending opens once Lacspace activates the workspace.
Security built in
Secure by default, not as an add-on
The protections below are on for every workspace from day one.
Hashed API keys
Keys are shown once and stored only as hashes. Rotate a key whenever you like.
Passwordless sign-in
One-time codes to your phone or email. Sessions live in httpOnly cookies.
Audit log
Every change in the dashboard is recorded with who, when and from where.
Watched phones
Sending phones report heartbeats and security events; a suspicious phone stops getting work.
Side by side
SMSRay vs a typical bulk-SMS gateway
What you get with SMSRay out of the box. Other providers differ, so check the details with whoever you use today.
| Capability | SMSRay | Typical bulk-SMS gateway |
|---|---|---|
| Who the message comes from | A real local mobile number on NTC, Ncell or Smart | Often a shared or generic sender |
| OTP generation and checking | Built in: we create, send, hash and verify the code | Usually build-it-yourself on top of plain send |
| Delivery receipts | Status per message: queued → sent → delivered, by API and webhook | Varies by provider |
| Webhook authenticity | HMAC-SHA256 signature with timestamp and secret rotation | Varies; sometimes unsigned |
| Safe retries | Idempotency-Key replays for 24 h, never a second SMS | Varies; retries can double-send |
| Replies from customers | Delivered to you as message.inbound, linked to the original | Often a separate product or not offered |
| Failed messages | One retry on another SIM, then refunded to your balance | Varies by provider |
| Unicode and Nepali | Exact GSM-7 / UCS-2 segment counts, never split mid-character | Varies by provider |
Plain REST
Five endpoints, one header (x-api-key) and one error shape. Examples in cURL, Node.js, Python and PHP.
Learn morePredictable errors
Every error is { error, code } with a stable code like insufficient_balance or rate_limited, plus Retry-After where it applies.
Learn moreBalance by API
Check your workspace balance with GET /sms/balance before a big send, and get a clean 402 if it runs short.
Learn more{ "error": "Rate limit exceeded", "code": "rate_limited" }
// HTTP 429 · Retry-After: 1Coming soon
On the roadmap
These are not available yet. We will announce each one when it ships.
Quiet hours
Hold non-urgent messages overnight, Nepal time.
STOP and opt-outs
Automatic opt-out on a STOP reply, plus blocklists.
Templates and contacts
Reusable message templates, contact lists and groups.
Bulk campaigns
Schedule one message to a list, paced across the pool.
Voice
Missed-call verification, call alerts and voice OTP.
Send your first SMS today
Create a workspace in a minute with your phone number or email. No card needed to explore the dashboard.