Migrate from AWS SES to Notify

Replace SES SDK sends with Notify’s HTTP API — keep your HTML, drop the AWS email ops tax.

SES is excellent transport. Notify is the thin DX layer when you do not want to own IAM, SNS bounce topics, and sandbox approval waits. See also Notify vs AWS SES.

What changes

AWS SESNotify
Recommended client@aws-sdk/client-ses (SendEmailCommand)One fetch — no SDK required
AuthIAM / AWS credentialsx-api-key
Call shapeSDK SendEmail / SendRawEmailPOST /api/email/send JSON
BodyHtml / Text message partsSingle message field
EventsSNS / EventBridge / CloudWatchLogs + webhooks (Pro/Scale)
Production accessOften sandbox → request productionVerify domain in Notify

Before / after

SES (AWS SDK v3)

import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';

const ses = new SESClient({ region: process.env.AWS_REGION });

await ses.send(
  new SendEmailCommand({
    Source: 'noreply@acme.com',
    Destination: { ToAddresses: ['user@example.com'] },
    Message: {
      Subject: { Data: 'Welcome' },
      Body: { Html: { Data: '<h1>Welcome</h1>' } }
    }
  })
);

Notify (one fetch — no SDK required)

await fetch('https://notify.cx/api/email/send', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.NOTIFY_API_KEY!,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    from: 'noreply@acme.com',
    to: 'user@example.com',
    subject: 'Welcome',
    message: '<h1>Welcome</h1>'
  })
});

Migration checklist

  1. Sign up and copy a Notify API key
  2. Verify the same sending domain in Notify (SPF/DKIM)
  3. Replace SES SDK calls with fetch / HTTP
  4. Point bounce/complaint handling at Notify webhooks instead of SNS (Pro/Scale)
  5. Keep SES around only if you still need it for other workloads

When to stay on SES

Very high volume, deep AWS ops maturity, or multi-region SES control where unit cost dominates and you already own logging/webhooks.

Where to next?