Migrate from Amazon SES without carrying AWS plumbing
Postscale replaces common SES setups with one email API: REST sending, SMTP relay, inbound webhooks, suppression management, DKIM, warming, and per-domain stats.
Migration scope
- Replace SendEmail or SendRawEmail with POST /v1/send.
- Swap SES SMTP credentials for Postscale SMTP relay credentials.
- Replace S3 plus Lambda receipt rules with inbound webhooks.
- Move account-level suppressions before production traffic.
What changes when you move
| Amazon SES | Postscale | Migration note |
|---|---|---|
| SendEmail API | POST /v1/send | Map Source/Destination/Message into from, to, subject, html_body, and text_body. |
| SMTP interface | Postscale SMTP relay | Change host, username, and password while leaving legacy SMTP clients in place. |
| Receipt rules | Inbound rules | Use aliases and rule conditions instead of S3, SNS, and Lambda wiring. |
| S3 raw MIME storage | Inbound Email API | Postscale stores parsed inbound messages and attachments without a custom parser. |
| Account suppression list | Suppression API | List account-level suppressed destinations by reason and preview the CSV before the first Postscale send. |
Cut over in controlled steps
Mirror DNS
Add Postscale verification, DKIM, return-path, and optional MX records while the old provider keeps sending.
Convert code
Swap API credentials and normalize the send payload. Keep the old provider path behind a feature flag for rollback.
Move state
Preview and import suppression exports, move template HTML, then configure delivery, bounce, complaint, and inbound webhooks.
Ramp traffic
Start at 10 percent, watch bounces and complaints by ISP, then increase volume as warming limits allow.
Send call conversion
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2";
const ses = new SESv2Client({ region: "eu-central-1" });
await ses.send(new SendEmailCommand({
FromEmailAddress: "Acme <alerts@example.com>",
Destination: { ToAddresses: ["user@example.com"] },
Content: {
Simple: {
Subject: { Data: "Welcome" },
Body: { Html: { Data: "<p>Hello from Acme</p>" } },
},
},
}));await fetch("https://api.postscale.io/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.POSTSCALE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "Acme <alerts@example.com>",
to: ["user@example.com"],
subject: "Welcome",
html_body: "<p>Hello from Acme</p>",
}),
});Production checklist
Frequently asked questions
What replaces SES receipt rules?
Postscale inbound aliases and rules replace the common S3/SNS/Lambda chain with signed webhook delivery and stored inbound messages.
Can legacy SMTP systems move first?
Yes. Change SMTP host and credentials to Postscale, then migrate REST sends later.
Do I still need to warm domains?
Yes. Any meaningful sender reputation move should ramp gradually. Postscale warming controls help enforce that ramp by domain and ISP.
How do SES suppressions move?
List the SES account-level suppression list, preserve bounce or complaint reason data, then import the CSV before moving production traffic.