Scenario: You sell messaging to resellers who each run campaigns for hundreds of end customers. A provider API returns 200 Accepted but half the messages never show as delivered. Wallets drift from carrier invoices. India DLT rejects templates you thought were approved. A generic “SMS API” blog will not help you—platform accounting and lifecycle will.
Direct answer
A multi-tenant CPaaS is a control plane: tenants → API/auth → policy & routing → provider adapter → delivery callbacks → reporting & wallets. It is not a single SMPP bind with a login screen.
Product scope: SMS & WhatsApp CPaaS. Engineering reference: multitenant messaging case study. Implementation: SaaS development.
Reference architecture
Tenant API / UI
→ auth (per-tenant keys, rate limits)
→ policy (DLT template, sender ID, opt-in for WhatsApp)
→ routing (provider selection, failover rules)
→ adapter (Kannel/SMPP, HTTP CPaaS)
→ provider network
← DLR / status callback (signed webhook)
→ ledger (wallet debit/credit, reconciliation)
→ reporting (per tenant, per reseller margin)
Tenant isolation: separate credentials, route tables, wallet balances, and audit logs. A reseller’s sub-tenant must not spend another reseller’s balance.
Message lifecycle (operational meanings)
| State | Meaning | Billing implication |
|---|---|---|
| Accepted | Platform validated request, enqueued | May reserve wallet units |
| Submitted | Handed to provider adapter | Debit often committed here |
| Delivered | Positive DLR (provider-defined) | Final for many prepaid models |
| Failed | Hard fail from provider | Refund or no debit per policy |
| Unknown | No callback within timeout | Reconciliation job; do not double-send blindly |
API acceptance ≠ final delivery. Design idempotency keys so client retries do not create duplicate sends.
Wallet accounting (synthetic walk-through)
Educational example—not a live customer ledger.
- Tenant balance: 10,000 SMS units.
- Campaign enqueue 500 messages → reserve 500 (available 9,500).
- Provider accepts 498, fails 2 → release reserve on 2, debit 498 on submit.
- DLRs arrive for 490 delivered, 8 unknown after 24h → reconciliation task compares provider CDR; adjust or escalate.
Double-debit prevention: row-level lock or ledger entries with idempotency on (tenant_id, client_message_id). Documented SandeshX build uses balance check + lock before enqueue—validate concurrency in UAT.
Idempotency, retries and webhooks
- Idempotency-Key on send API; store outcome before returning 200 to client.
- Retries only on safe states (network timeout to provider), not after ambiguous accept.
- Webhook security — HMAC signature, replay window, IP allowlist where provider supports it.
- Rate limits per tenant to protect provider binds and your own stability.
India DLT vs global routes
| Topic | India DLT | Typical global HTTP/SMPP |
|---|---|---|
| Template | Registered template ID required for many routes | Provider-specific template/content rules |
| Entity | Principal entity registration | Business verification per provider |
| Sender ID | Approved headers | Alphanumeric / long codes per country |
| Platform role | Model PE, template, sender in DB; customer owns legal registration | Contract + KYC with aggregator |
WhatsApp adds opt-in, template categories, service windows, per-message provider charges—scope separately from SMS.
Multi-provider and failover
Running two SMS providers can improve reach but failover without deduplication can duplicate messages if the first provider eventually delivers after timeout. Policy: primary/secondary with idempotent provider message IDs and strict timeout rules.
What we do not promise unless scoped
- Carrier delivery SLAs
- Legal sign-off on DLT/GDPR
- WhatsApp Business onboarding fees
- Full tax invoicing in every country
Provider failure handling
| Failure mode | Platform behavior (design target) | Risk if ignored |
|---|---|---|
| SMPP bind down | Queue or fail fast with alert | Silent message loss |
| HTTP 5xx from CPaaS | Retry with backoff + idempotency | Duplicate sends |
| Slow DLR | Unknown state + reconciliation | Wrong wallet balance |
| Partial batch accept | Per-message status in API response | Client assumes all sent |
Run game days: kill bind, delay callbacks, replay webhooks—verify ledger matches provider CDR.
Acceptance criteria for a reseller launch
- Tenant cannot read another tenant’s messages or balance
- Idempotent resend with same key does not double debit
- DLT-blocked template rejected before provider submit (India)
- WhatsApp template outside service window rejected with clear API error
- Reseller parent sees margin report matching child usage
- Webhook signature verification enabled in production
Connected path on this site
Article (architecture) → SandeshX case study (evidence) → product estimator (scoped build).
Author note: Platform patterns described here reflect documented builds; your carrier contracts and compliance remain your responsibility.
Estimator: messaging scope — tenants, volume, provider path—not PBX seat counts.
Next step: Request a messaging platform proposal · Case study