MailerSend
Send through the MailerSend Email API with cc/bcc, headers, tags, attachments, and a single reply-to address.
The MailerSend adapter calls the MailerSend Email API over fetch — no extra dependency. Its quirk: MailerSend accepts exactly one reply-to address, and the message id comes back in the x-message-id response header rather than the body.
@opencoredev/email-sdk/mailersendConfigure
Create an API token in the MailerSend dashboard and verify the domain you plan to send from.
import { createEmailClient } from "@opencoredev/email-sdk";
import { mailersend } from "@opencoredev/email-sdk/mailersend";
export const email = createEmailClient({
adapters: [mailersend({ apiKey: process.env.MAILERSEND_API_KEY! })],
});Prop
Type
Send
MailerSend maps cc, bcc, headers, attachments (an attachment's contentId becomes MailerSend's id), and tags (values only). replyTo accepts a single address — two or more throw an EmailValidationError before any request.
const result = await email.send({
from: "Acme <hello@acme.com>",
to: [{ email: "user@example.com", name: "Ada" }],
replyTo: "support@acme.com",
subject: "Reset your Acme password",
html: "<p>Click the link below to choose a new password.</p>",
tags: [{ name: "type", value: "password-reset" }],
});
console.log(result.id); // MailerSend message id from the x-message-id headerThe response id comes from the x-message-id response header, falling back to message_id or id in the body — use it to look the send up in MailerSend's activity log.
No metadata field
MailerSend has no metadata concept, so metadata on a message throws an
EmailValidationError before any request is made. Use tags instead, or pick a
metadata-capable adapter. MailerSend also gates custom
headers behind its Professional and Enterprise plans.
Verify from the CLI
MAILERSEND_API_KEY="mlsn..." npx email-sdk doctor --adapter mailersendMAILERSEND_API_KEY="mlsn..." npx email-sdk send \
--adapter mailersend \
--from "Acme <hello@acme.com>" \
--to user@example.com \
--subject "MailerSend smoke test" \
--text "It works" \
--dry-runDrop --dry-run for one real send — that is the only check that proves the token, domain verification, and plan limits are ready.
