MailerSend vs AWS SES
MailerSend and Amazon SES are the managed-service-versus-infrastructure trade in its purest form. SES keeps costs near the floor at scale — à -la-carte outbound at $0.10 per 1K sends — and sits inside the AWS ecosystem — IAM credentials, CloudWatch metrics, regional endpoints — in exchange for you owning deliverability: dedicated IPs, configuration sets, and bounce processing are all your job, and the console is unmistakably AWS. MailerSend, the transactional arm of the MailerLite family, wraps sending in a product instead: a template gallery with a drag-and-drop editor, a 500-send free tier, and a clean REST API, at a higher per-message price. In the unified message shape MailerSend covers the full common surface except per-message metadata, including native scheduled sending; SES supports neither scheduling nor metadata, so a MailerSend-to-SES fallback drops sendAt and Email SDK's field checks flag it before the send.
Message field support
Field support as encoded in Email SDK's own adapter capability matrix — the same data the SDK uses to reject sends that would silently drop fields.
| Message field | MailerSend | AWS SES |
|---|---|---|
| CC recipients | ✓ | ✓ |
| BCC recipients | ✓ | ✓ |
| Reply-To address | ✓ | ✓ |
| Custom headers | ✓ | ✓ |
| Attachments | ✓ | ✓ |
| Tags | ✓ | ✓ |
| Metadata | — | — |
| Scheduled sending (sendAt) | ✓ | — |
Fallback compatibility
Failing over from MailerSend to AWS SES loses: Scheduled sending (sendAt). Email SDK rejects the fallback send for messages that use these fields instead of dropping them silently.
Same code, either provider
With Email SDK the send call is identical for both providers — only the adapter import changes:
import { createEmailClient } from "@opencoredev/email-sdk";
import { mailersend } from "@opencoredev/email-sdk/mailersend";
const client = createEmailClient({
adapters: [mailersend({ apiKey: process.env.MAILERSEND_API_KEY! })],
});
await client.send({
from: "hello@yourdomain.com",
to: "user@example.com",
subject: "Welcome!",
html: "<p>It works.</p>",
});Or run both, with automatic fallback:
import { createEmailClient } from "@opencoredev/email-sdk";
import { mailersend } from "@opencoredev/email-sdk/mailersend";
import { ses } from "@opencoredev/email-sdk/ses";
const client = createEmailClient({
adapters: [
mailersend({ apiKey: process.env.MAILERSEND_API_KEY! }),
ses({
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
region: "us-east-1",
}),
],
defaultAdapter: "mailersend",
fallback: ["ses"],
});FAQ
- Can I switch from MailerSend to AWS SES without rewriting my email code?
- Yes. With Email SDK both providers share one typed send() call and one message shape, so switching from MailerSend to AWS SES is a one-line adapter change plus an API key. The SDK fails fast if a message uses a field AWS SES does not support, so nothing is silently dropped.
- Which message fields does MailerSend support that AWS SES doesn't?
- MailerSend supports Scheduled sending (sendAt) in the unified message shape, which AWS SES does not.
- Can I use AWS SES as a fallback for MailerSend?
- Partially. Email SDK checks field support before every send: a fallback from MailerSend to AWS SES is rejected for messages using Scheduled sending (sendAt). Messages that avoid those fields fail over cleanly.
Adapter docs
Setup guides: MailerSend adapter and AWS SES adapter. Sending from your own domain? Verify SPF, DKIM, and DMARC with the free email DNS checker.