Skip to Content

MSG91

Category: Notification — SMS
Package: @leadmetrics/provider-smsMsg91Provider
External SDK: axios (direct REST API calls)


Purpose

MSG91 is the platform default SMS provider, targeting the Indian market. All tenants get SMS notifications from the platform’s MSG91 account out of the box. Tenants can bring their own MSG91 account for messages to arrive from their own registered sender ID (e.g. “ACMEPLMB” instead of “LEADMTX”).

MSG91 sender IDs must be pre-registered with TRAI (India’s telecom regulator). International SMS is not the primary use case — use Twilio for international.


What it sends

Notification typeTrigger
HITL review request (SMS)Activity reaches pending_approval
Budget warning (SMS)Credits drop below 20% threshold
Report ready (SMS)Monthly report generated
OTP / auth (future)2FA or login codes

Config Structure

Platform default (env vars)

SMS_API_KEY=your_msg91_api_key SMS_FROM=LEADMTX # 6-character TRAI-registered sender ID SMS_API_BASE_URL=https://api.msg91.com/api/v5

Tenant config (stored in notification_providers.config, encrypted)

interface Msg91Config { apiKey: string; // MSG91 API key senderId: string; // 6-character alphanumeric sender ID registered with TRAI baseUrl: string; // usually "https://api.msg91.com/api/v5" — allow override for future API versions }

Integration Pattern

Provider class (packages/provider-sms/src/providers/msg91.ts)

MSG91 uses a simple REST API. The platform calls the sendotp or flow endpoints depending on the message type.

import axios from 'axios'; class Msg91Provider implements SmsProvider { readonly name = 'msg91'; constructor( private apiKey: string, private senderId: string, private baseUrl: string, ) {} async send(message: SmsMessage): Promise<SmsSendResult> { const response = await axios.post( `${this.baseUrl}/flow/`, { sender: this.senderId, mobiles: message.to, // E.164 format: "+919876543210" message: message.body, }, { headers: { 'authkey': this.apiKey, 'Content-Type': 'application/json', 'Accept': 'application/json', }, }, ); if (response.data.type !== 'success') { throw new Error(`MSG91 send failed: ${response.data.message}`); } return { messageId: response.data.request_id, provider: 'msg91', status: response.data.type, }; } async verify(): Promise<void> { // MSG91 doesn't have a ping endpoint; call balance/account info as a connectivity check const response = await axios.get(`${this.baseUrl}/balance`, { headers: { authkey: this.apiKey }, }); if (response.status !== 200) { throw new Error(`MSG91 verification failed: HTTP ${response.status}`); } } }

Phone number format

MSG91 accepts E.164 format. The to field in SmsMessage must be +91XXXXXXXXXX for Indian numbers. The notification system normalises phone numbers to E.164 from the tenant_users.phone field before dispatch.

DLT registration (India)

MSG91 requires DLT (Distributed Ledger Technology) registration for promotional and transactional SMS. The platform’s registered DLT template IDs must be set per message type. These are stored in the platform env config:

MSG91_DLT_TEMPLATE_HITL=1007xxxxxxxxxx MSG91_DLT_TEMPLATE_BUDGET=1007xxxxxxxxxx MSG91_DLT_TEMPLATE_REPORT=1007xxxxxxxxxx

For tenant accounts, the tenant’s DLT template IDs are stored in Msg91Config or as a separate table column.


Test Cases

Unit tests (packages/provider-sms/src/providers/msg91.test.ts)

TestApproach
send() POSTs to correct MSG91 endpointMock axios.post; assert URL and headers
send() includes authkey, sender, mobiles, messageAssert request body fields
send() returns messageId from request_idMock response { type: 'success', request_id: 'abc' }
send() throws on type !== 'success'Mock response { type: 'error', message: 'Invalid API Key' }
send() throws on network errorMock axios.post rejects; assert error propagated
verify() calls balance endpointMock axios.get; assert URL and authkey header
verify() throws on non-200Mock 401; assert throws

Integration tests

TestApproach
Send SMS against MSG91 sandboxUse MSG91 test credentials; assert request_id returned
Platform default used when no tenant rowSeed no notification_providers row; assert Msg91Provider uses env vars
Tenant MSG91 used when verifiedSeed verified msg91 row; assert Msg91Provider uses tenant apiKey

Dev / staging

In dev mode, filterRecipientsForDev() replaces all to phone numbers with DEV_PHONE_OVERRIDE. No real SMS is sent to end users during development.


Sender ID Registration

To use the platform sender ID, the following must be registered on TRAI’s DLT portal:

FieldValue
Entity nameLeadmetrics Technologies
Sender IDLEADMTX
CategoryTransactional
TemplatesAll 18 notification type templates

Tenants must register their own sender IDs through their MSG91 account and DLT portal before using a custom sender.


© 2026 Leadmetrics — Internal use only