---
title: "MSG91"
description: "Use MSG91 for MainSDK SMS and WhatsApp notifications and WhatsApp sign-in codes in India - DLT templates, main.yaml, secrets and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/msg91"
updated: "2026-10-28"
---

# MSG91

> Use MSG91 for MainSDK SMS and WhatsApp notifications and WhatsApp sign-in codes in India - DLT templates, main.yaml, secrets and swapping.

Canonical: https://mainsdk.dev/docs/integrations/msg91 · Updated: 2026-10-28

MSG91 is an India-based messaging provider for SMS and WhatsApp. In a MainSDK app it is an SMS driver and a WhatsApp channel driver for [`notify`](https://mainsdk.dev/docs/interfaces/notify), and a sender for WhatsApp one-time codes in [`auth`](https://mainsdk.dev/docs/interfaces/auth). Pick it when most of your users are in India and you want SMS and WhatsApp from one provider.

## Interfaces it serves

### Notifications (`notify`)

- Status: Building for 0.3 · ships as a stable API
- Driver: `msg91` (MSG91)
- Docs: https://mainsdk.dev/docs/interfaces/notify.md

```yaml
notify:
  driver: msg91
```

Swap to another provider: `whatsapp-cloud`, `bird`, `twilio`, `local`, `fcm`, `apns`, `expo`, `resend`, `ses`, `onesignal`, `slack`, `pagerduty`, `opsgenie`, `webhook`.

## Before you start

1. Create an MSG91 account and an auth key for this app.
2. For SMS in India, register your sender ID and message templates on the DLT platform, then add them in MSG91.
3. For WhatsApp, connect a WhatsApp Business number through MSG91 and get your templates approved.

Store the auth key in your secrets manager.

## Configure

```yaml title="main.in.yaml"
notify:
  channels: [whatsapp, sms, push, email]
  sms: msg91
  whatsapp: msg91
  msg91:
    key: secret:MSG91_AUTH_KEY             # the auth key; this is the default name
    whatsapp:
      number: "919876500000"               # the integrated WhatsApp number
      namespace: acme_namespace            # the WhatsApp template namespace
  templates:
    order.shipped:
      sms: { template: "64f0c0ffee", vars: [orderId], dlt-template-id: "1007000000000001" }
      whatsapp: { name: order_shipped, language: en, params: [orderId] }
auth:
  whatsapp: { driver: msg91 }
```

- `key` defaults to `secret:MSG91_AUTH_KEY`. A literal key fails validation with `MAIN-CONFIG-0004`.
- `whatsapp.number` and `whatsapp.namespace` are needed only when `notify.whatsapp` is `msg91`.
- MSG91 sends SMS from its own flow template, so each SMS template needs `template` (the MSG91 flow id) and `vars`, the `data` keys in the order the flow takes them. A template with only `text` is skipped on SMS with the reason `failed` and the code `MAIN-NOTIFY-0001`. Set `dlt-template-id` for India numbers too; without it a `+91` number is skipped with `MAIN-NOTIFY-0005`.

> **Warning:** The MSG91 request shapes are written from MSG91's documentation and are unverified against the live API. Verify with a sandbox key before production: send one SMS and one WhatsApp template message to your own number first, with the templates approved in MSG91.

### What the drivers send

SMS is one `POST https://control.msg91.com/api/v5/flow` with an `authkey` header and a JSON body holding `template_id`, `short_url: "0"` and one recipient with its `mobiles` (digits, no plus) and the template variables. WhatsApp is one `POST https://control.msg91.com/api/v5/whatsapp/whatsapp-outbound-message/bulk/` with `integrated_number` and a template payload: the template name, the language, the namespace, and the body variables numbered `body_1`, `body_2` in the order of `params`. Both go through MainSDK's network layer, are never retried by it, do not follow redirects, and read at most 64 KiB of the answer. A 429, a 5xx or no answer is a retryable `MAIN-NOTIFY-0007` and `notify` tries the next channel. MainSDK does not read MSG91's delivery reports.

## Use it

```ts title="app/orders/ship.ts"
import { notify } from "mainsdk";

await notify(user, { template: "order.shipped", data: { orderId: order.id }, category: "orders" });
```

`auth.whatsapp.send(phone)` and `auth.whatsapp.verify(challengeId, code)` work the same with MSG91 as the sender.

## Local development and testing

`mainsdk dev` logs one line per SMS and WhatsApp message with the number masked, when `notify.sms` and `notify.whatsapp` are `local`. `createTestApp()` from `@mainsdk/testing` runs `notify` on local channels; read them with `channels(app)`. `channels(app).sms?.failNext(1)` simulates an outage, and `fakeMessagingServer("msg91")` records the requests the real drivers make.

## What MainSDK adds on top

- Every SMS recipient has a recorded opt-in (`MAIN-NOTIFY-0003` otherwise), and India SMS uses DLT-registered templates.
- WhatsApp only with recorded consent (`MAIN-NOTIFY-0004` otherwise) and approved templates.
- Opt-outs and quiet hours respected; a retry never sends twice.

See [Notifications](https://mainsdk.dev/docs/interfaces/notify).

## Limits and notes

- The SMS and WhatsApp channel drivers are built (spec `email-notify`). The `auth.whatsapp` sender comes with the auth spec.
- A MainSDK template maps to MSG91 through `notify.templates.<name>.sms.template` and `.vars`, and to a DLT template through `.sms.dlt-template-id`.
- The drivers declare their own host, `control.msg91.com`, so `network.allow` does not change.

## Swap to or from it

```yaml title="main.yaml"
notify:
  sms: twilio   # was msg91
```

Add the new provider's block, such as `notify.twilio`, with it. Sending is stateless, so the swap needs no migration. Your DLT templates and WhatsApp approvals are registered per provider, so set them up with the new one first.

## FAQ

**Can I use MSG91 only in India?** Yes. Set it in the `main.in.yaml` market overlay and keep another driver in `main.yaml`.

**Does MSG91 pass the same tests as the others?** Yes. The SMS cases pass for Twilio and MSG91, and the WhatsApp cases for WhatsApp Cloud API, Bird and MSG91.

## Next

- [Notifications](https://mainsdk.dev/docs/interfaces/notify) and [Sign-in and sessions](https://mainsdk.dev/docs/interfaces/auth)
- [Twilio](https://mainsdk.dev/docs/integrations/twilio), [WhatsApp](https://mainsdk.dev/docs/integrations/whatsapp) and [Bird](https://mainsdk.dev/docs/integrations/bird)
