Guides

Failover

Retry inside a provider, then fail over across providers on any channel.

When a provider blips, retry that transport first, then fail over to the next. The same decorator pattern works for email, SMS, WhatsApp, and push.

The one rule

Wrap each provider in RetryTransport, then pass the list to FallbackTransport. Use the channel sender that matches the transport contract.

Quick start

import { createMailer } from "sently/mailer";
import { FallbackTransport } from "sently/transports/fallback";
import { RetryTransport } from "sently/transports/retry";
import { ResendTransport } from "sently/transports/resend";
import { SESTransport } from "sently/transports/ses";

const mailer = await createMailer({
  transport: new FallbackTransport(
    [
      new RetryTransport(new ResendTransport({ apiKey: process.env.RESEND_API_KEY! })),
      new RetryTransport(
        new SESTransport({
          region: process.env.AWS_REGION!,
          accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
          secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
        }),
      ),
    ],
    { cooldownMs: 300_000 },
  ),
});
import { createSmsSender } from "sently/sms";
import { FallbackTransport } from "sently/transports/fallback";
import { RetryTransport } from "sently/transports/retry";
import { TwilioSmsTransport } from "sently/transports/twilio-sms";
import { UnifonicTransport } from "sently/transports/unifonic";

const sms = createSmsSender({
  transport: new FallbackTransport(
    [
      new RetryTransport(
        new TwilioSmsTransport({
          accountSid: process.env.TWILIO_ACCOUNT_SID!,
          authToken: process.env.TWILIO_AUTH_TOKEN!,
        }),
      ),
      new RetryTransport(
        new UnifonicTransport({
          appSid: process.env.UNIFONIC_APPSID!,
          senderId: "MyBrand",
        }),
      ),
    ],
    { cooldownMs: 300_000 },
  ),
});
const result = await sms.send({
  to: "+15551234567",
  body: "Hello",
  from: "+15557654321",
});
console.log(result.provider, result.providerIndex);

Behavior

BehaviorDefault
Fail over on 5xx / networkYes
Fail over on 400 / 401 / 403No (same client error on every provider)
cooldownMsSkip a failed provider until the cooldown ends
HooksonRetry / onFallback on the channel sender when wired

Troubleshooting

Learn more

Next

On this page