Skip to content
SMS21
API operational

One API for OTP, SMS and WhatsApp

SMS21 routes every message to the right provider, fails over when one is down, enforces DLT rules, reports delivery and bills from a prepaid wallet — so your applications never integrate a telecom vendor directly.

  • Free sandbox keys
  • No provider contracts
  • First OTP in five minutes
Send a one-time password from your server
curl -X POST https://sms21.in/v1/otp/send \
  -H "X-API-Key: $SMS21_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mobile":"919876543210","purpose":"login"}'
{
  "success": true,
  "requestId": "otp_01k55q8y4m3d9v7x2c6b0n1r8t",
  "status": "pending",
  "channel": "sms",
  "expiresIn": 300,
  "resendAfter": 30,
  "messageId": "msg_01k55q8y4m3d9v7x2c6b0n1r8t"
}
Delivers throughTwilioMSG91WhatsApp Business Cloud APIa built-in sandbox

Channels

Every message your product sends, behind one integration

Authentication codes, order updates, campaigns and replies share the same keys, the same delivery reporting and the same wallet.

OTP

One-time passwords over SMS or WhatsApp. Codes are hashed at rest, rate limited per mobile and purpose, expire on a timer and fall back to a second channel.

Read the guide

Transactional SMS

DLT-approved templates and sender IDs, automatic encoding and segment counting, and idempotency keys so a retry never sends twice.

Read the guide

Bulk campaigns

Send to thousands of numbers from a contact list or CSV, schedule ahead, watch progress, stop mid-flight, and honour the opt-out list automatically.

Read the guide

WhatsApp

Template, authentication and session messages on the WhatsApp Business Cloud API, with the same delivery reporting as SMS.

Read the guide

Inbound & opt-outs

Receive replies on your numbers, handle STOP and START keywords, and keep a suppression list the sending APIs respect.

Read the guide

Delivery status

One set of statuses across every provider, queryable per message or in bulk, with the provider’s own response kept for support.

Read the guide

Developers

Built to be integrated in an afternoon

A predictable REST API, typed SDKs and a sandbox that behaves like production without sending or charging anything.

  • OpenAPI 3.1 document and an interactive reference, ready for Postman or a code generator.
  • Idempotency keys on every write, so a retried request never sends or charges twice.
  • Stable error codes with documented retry guidance instead of provider-specific strings.
  • SDKs and examples for Node.js, NestJS, Next.js, PHP, Laravel and plain cURL.
Check the code the user typed
curl -X POST https://sms21.in/v1/otp/verify \
  -H "X-API-Key: $SMS21_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requestId":"otp_…","otp":"123456","mobile":"919876543210"}'

The response never contains the code, attempts are capped per request, and every outcome — expired, attempts_exceeded, already_verified — is a value you can branch on.

Getting started

From sandbox to live traffic in three steps

  1. 1

    Create a test key

    Register, create a company and a project, then issue a key that starts with sms21_test_ and scope it to what the application needs.

  2. 2

    Send your first message

    Call the API from your server. The sandbox accepts everything, delivers nothing, charges nothing, and every OTP code is 123456.

  3. 3

    Go live

    Register DLT templates, fund the wallet, swap in a live key restricted to your server IPs, and point a webhook at your status endpoint.

Platform

The parts nobody wants to build twice

Routing, compliance, reconciliation and reporting are the reason an SMS integration takes months. They are the product here.

Routing and failover

Providers are ranked per country and channel. When one stops accepting traffic the next takes over, without a code change on your side.

Signed webhooks

Subscribe to message.delivered and message.failed. Every delivery is HMAC-signed, retried on failure and replayable from the dashboard.

DLT compliance built in

Entity, sender IDs and templates live in the platform. Messages are matched to an approved template before a provider ever sees them.

Prepaid wallet and ledger

Prices are set per company, channel, message type and destination. Every charge, refund and top-up is an immutable ledger entry.

Projects, roles and keys

Separate projects per application, role-based permissions per member, and scoped API keys you can restrict to your servers’ IP addresses.

Reports and dashboards

Messages, delivery, inbound, failures, usage and API request logs — filterable in the dashboard and available over the API.

Pricing

Prepaid wallet. Charged per message.

No seats to count and no plan to outgrow. Top up the wallet, and every message is priced by channel, message type and destination country at the moment it is sent.

Top up when you need to

Add funds from the dashboard and spend them across every project and channel in the company. Low-balance alerts warn you before sending stops.

Rates that match your volume

Prices are agreed per company and recorded with the date they take effect, so an old charge is always explained by the rate in force that day.

GST invoices and a full ledger

Every charge, refund and top-up is a ledger entry you can filter and export, and each top-up produces a GST invoice for your books.

Test keys are never charged — build the whole integration before you fund anything.

Security & compliance

Credentials, money and regulated traffic — treated that way

Messaging touches your users’ phone numbers, your telecom compliance and your balance. Every one of those paths is authenticated, scoped and logged.

  • Argon2id password hashing and encrypted secrets at rest
  • TOTP second factor, mandatory for Super Admins
  • Scoped API keys with IP allow-lists and rotation
  • Audit log of every administrative action
  • Per-project rate limits and idempotent writes
  • Strict Content-Security-Policy with per-request nonces

Questions

Before you write any code

Everything else is in the documentation.

Do I have to sign contracts with Twilio or MSG91 myself?

No. SMS21 holds the provider accounts and exposes one API. Routing rules decide which provider carries each message by country, channel and priority, and the platform fails over to the next provider when one stops accepting traffic.

Can I build and test without sending real messages?

Yes. Every project gets test keys beginning with sms21_test_. They run against a built-in sandbox: nothing is delivered, nothing is charged, and every OTP code is 123456. Only sms21_live_ keys send real messages.

Does SMS21 handle DLT registration for India?

SMS21 manages your DLT entity, sender IDs and template registry, and validates every message against an approved template before it reaches a provider, so non-compliant traffic is rejected by the API rather than by the operator.

How do I find out whether a message was delivered?

Provider callbacks are normalised into one set of statuses. Read them with GET /v1/messages/{messageId}, in the dashboard reports, or subscribe to HMAC-signed webhooks for message.delivered and message.failed, which are retried and can be replayed.

What does it cost?

Billing is a prepaid wallet. Each message is priced per channel, message type and destination country, and charged at send time; the ledger records every charge, refund and top-up. Top up from the dashboard and download a GST invoice.

Can my whole team use one account?

A company can hold several projects and members. Roles and permissions decide what each member sees and does, API keys are scoped per project and can be restricted to your servers’ IP addresses, and administrative accounts require a TOTP second factor.

Start today

Send your first one-time password in five minutes

Create an account, issue a test key and call the API. Nothing is delivered and nothing is charged until you switch to a live key.