Channels
SMS
Send SMS notifications
The SMS channel is provided by @betternotify/sms. It defines a single body slot for text message content.
When to use SMS
SMS is the right channel when the message needs to reach the recipient immediately on their phone, regardless of whether they have your app installed or an internet connection. Use it for OTP codes, two-factor authentication, appointment reminders, delivery updates, or urgent alerts where reliability and reach matter more than rich formatting.
npm install @betternotify/smsSetup
import { createNotify } from '@betternotify/core';
import { smsChannel } from '@betternotify/sms';
const sms = smsChannel();
const rpc = createNotify({ channels: { sms } });Slots
Prop
Type
Send arguments
Prop
Type
Full example
import { createNotify, createClient } from '@betternotify/core';
import { createMockTransport } from '@betternotify/core/transports';
import { smsChannel } from '@betternotify/sms';
import { z } from 'zod';
const sms = smsChannel();
const rpc = createNotify({ channels: { sms } });
const catalog = rpc.catalog({
otpCode: rpc
.sms()
.input(z.object({ code: z.string().length(6) }))
.body(({ input }) => `Your verification code is ${input.code}. It expires in 10 minutes.`),
});
const notify = createClient({
catalog,
transportsByChannel: { sms: createMockTransport() },
});
await notify.otpCode.send({
to: '+15555555555',
input: { code: '482910' },
});Transport
The SMS channel produces a RenderedSms with body and to. Any transport that accepts this shape works.
Twilio
The @betternotify/twilio package provides a ready-made transport:
import { twilioSmsTransport } from '@betternotify/twilio';
const transport = twilioSmsTransport({
accountSid: process.env.TWILIO_ACCOUNT_SID!,
authToken: process.env.TWILIO_AUTH_TOKEN!,
fromNumber: process.env.TWILIO_FROM_NUMBER!,
});Custom
Use createTransport to build a transport for any SMS provider (AWS SNS, Vonage, etc.):
import { createTransport } from '@betternotify/core/transports';
import type { RenderedSms } from '@betternotify/sms';
const myTransport = createTransport<RenderedSms>({
name: 'my-sms',
send: async (rendered) => {
// Call your provider's API with rendered.to and rendered.body
return { ok: true, data: { messageId: '...' } };
},
});