Email
Custom Email Adapter
Build a custom VitNode email adapter for any third-party provider like Postmark, AWS SES, or Mailgun.
You can connect any transactional email service (e.g. Postmark, AWS SES, SendGrid, Mailgun) by implementing the EmailApiPlugin interface. VitNode handles template rendering, i18n localization, and recipient resolution; your adapter just sends the email.
The EmailApiPlugin Interface
The adapter contract consists of a single sendEmail method:
export interface EmailApiPlugin {
sendEmail: (args: {
to: string
subject: string
html: string
text: string
metadata: { title: string; shortTitle?: string }
replyTo?: string
}) => Promise<void>
}Quick start: Implementing an Adapter
1. Create the Adapter Factory
import type { EmailApiPlugin } from "@vitnode/core/api/models/email"
export const PostmarkEmailAdapter = ({
serverToken,
from,
}: {
serverToken: string
from: string
}): EmailApiPlugin => ({
sendEmail: async ({ to, subject, html, text, metadata }) => {
const res = await fetch("https://api.postmarkapp.com/email", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"X-Postmark-Server-Token": serverToken,
},
body: JSON.stringify({
From: `${metadata.shortTitle ?? metadata.title} <${from}>`,
To: to,
Subject: subject,
HtmlBody: html,
TextBody: text,
}),
})
if (!res.ok) throw new Error(`Postmark error: ${res.statusText}`)
},
})2. Register in API Configuration
Attach the adapter to vitNodeApiConfig in apps/api/src/vitnode.api.config.ts:
import { buildApiConfig } from "@vitnode/core/vitnode.config"
import { PostmarkEmailAdapter } from "./lib/email/postmark-adapter"
export const vitNodeApiConfig = buildApiConfig({
email: {
adapter: PostmarkEmailAdapter({
serverToken: process.env.POSTMARK_SERVER_TOKEN!,
from: "notifications@yourdomain.com",
}),
},
})sendEmail Arguments
Prop
Type