Skip to main content

Guides

Providers

Every supported email provider, its import path, and constructor options.


Each provider is its own entry point, so you only bundle the one you import. Every provider exposes the same send() and is_error() methods — swap providers without changing your calling code.

Provider Import Constructor options
Amazon SES postboi/ses access_key_id, secret_access_key, region, session_token?
Brevo postboi/brevo api_key
Cloudflare postboi/cloudflare api_key, account_id
Elastic Email postboi/elasticemail api_key
MailerSend postboi/mailersend api_key
Mailgun postboi/mailgun api_key, domain, region?
Mailjet postboi/mailjet api_key, api_secret
MailPace postboi/mailpace api_key
Mailtrap postboi/mailtrap api_key, sandbox?, inbox_id?
Mandrill postboi/mandrill api_key
Microsoft 365 postboi/microsoft365 tenant_id, client_id, client_secret
Plunk postboi/plunk api_key
Postmark postboi/postmark api_key, message_stream?
Resend postboi/resend api_key
Scaleway postboi/scaleway secret_key, project_id, region
SendGrid postboi/sendgrid api_key, region?
SMTP (any) postboi/smtp host, port?, user?, pass?, secure?
SparkPost postboi/sparkpost api_key, region?
ZeptoMail postboi/zepto api_key
Mock (testing) postboi/mock none

Want another provider? Quit being a baby and open a PR.

Using a provider directly

Useful when you want an explicit instance, or you’re on a runtime without ambient env vars (e.g. Cloudflare Workers):

import Resend from 'postboi/resend';

const mail = new Resend({
	api_key: process.env.RESEND_API_KEY!,
	default: { from: 'no-reply@example.com' }
});

await mail.send({
	to: 'someone@example.com',
	subject: 'hello',
	body: '<p>hello world</p>'
});
import Resend from 'postboi/resend';

const mail = new Resend({
	api_key: process.env.RESEND_API_KEY!,
	default: { from: 'no-reply@example.com' }
});

await mail.send({
	to: 'someone@example.com',
	subject: 'hello',
	body: '<p>hello world</p>'
});

Every provider also accepts default, timeout, retries, retry_delay, auto_text, and hooks on top of its own credentials — see Common constructor options.

Mock provider

postboi/mock records messages in-memory instead of sending them — same normalisation as a real provider. Perfect for tests.

import Mock from 'postboi/mock';

const mail = new Mock({ default: { from: 'no-reply@example.com' } });
await mail.send({ to: 'contact@example.com', subject: 'Hi', body: '<p>Hello</p>' });

expect(mail.sent).toHaveLength(1);
import Mock from 'postboi/mock';

const mail = new Mock({ default: { from: 'no-reply@example.com' } });
await mail.send({ to: 'contact@example.com', subject: 'Hi', body: '<p>Hello</p>' });

expect(mail.sent).toHaveLength(1);

Custom headers & tags

headers and tags on send() are forwarded to each provider’s native concept, and quietly ignored where unsupported:

  • headers → Resend, Postmark, SendGrid, Mailgun (h:), Brevo, SparkPost, Mandrill, Plunk, Mailtrap, Scaleway, Cloudflare, SES, Mailjet, Elastic Email.
  • tags → SendGrid (categories), Mailgun (o:tag), Brevo, MailerSend, Mandrill, MailPace, SES (EmailTags), Resend ({name,value} pairs). Postmark and Mailtrap use the first tag only.