Payload CMS integration

Sending Emails from Payload CMS with Sweego

Payload CMS has established itself as one of the most popular headless CMS solutions in the TypeScript ecosystem. Code-first, strongly typed, and built for modern architectures — it’s a natural fit for teams who want full control over their stack.

By default, Payload sends its system emails (password resets, user invitations, notifications) via Nodemailer. If you want to replace this behavior with a dedicated sending API, Payload natively exposes an email adapter system.

Zapal Tech, a TypeScript-focused web development agency, has built and open-sourced an official adapter for Sweego: @zapal/payload-email-sweego.

A big thank you to them for this integration 🙂

Why use Sweego for email sending in Payload CMS?

When Payload sends an email, it goes through the adapter layer defined in your config. By default, that’s Nodemailer over SMTP. This works, but it means managing an SMTP server, connection timeouts, queue handling, and limited observability.

Switching to the Sweego REST API brings concrete advantages for a Payload project:

  • Controlled deliverability: dedicated IP reputation, DKIM/SPF authentication managed on the Sweego side
  • Real-time logs: every sent email is traceable in the Sweego dashboard
  • No SMTP dependency: a simple HTTPS call — no port 587 to open in your infrastructure
  • Clean integration: the adapter plugs in exactly where Payload intends, with no patching or monkey-patching required

Installation

The adapter is available on npm. With pnpm:

pnpm add @zapal/payload-email-sweego

With npm or yarn:

npm install @zapal/payload-email-sweego
# ou
yarn add @zapal/payload-email-sweego

Configuration

1. Add your API key as an environment variable

# .env
SWEEGO_API_KEY=votre_cle_api_sweego

You can create and manage your API keys from your Sweego dashboard.

2. Configure the adapter in payload.config.ts

import { buildConfig } from 'payload/config'
import { sweegoAdapter } from '@zapal/payload-email-sweego'

export default buildConfig({
  email: sweegoAdapter({
    defaultFromAddress: 'no-reply@votredomaine.com',
    defaultFromName: 'Votre Application',
    apiKey: process.env.SWEEGO_API_KEY || '',
  }),
  // ... reste de votre config Payload
})

That’s it. Payload will now route all its system emails through the Sweego API.

How it works

The adapter implements Payload CMS’s native EmailAdapter interface. Every time Payload triggers an email send (forgot password, user invitation, etc.), the adapter translates the request into a call to the Sweego /send API endpoint with the appropriate parameters:

  • channel: "email"
  • provider: "sweego"
  • the from, to, subject, and message body fields

Authentication is handled via the Api-Key header on each request.

Sender domain

The domain used in defaultFromAddress must be verified in your Sweego account. Emails sent from an unverified domain will be rejected by the API.

Things to keep in mind

Sender address format — Payload sometimes passes the from address as "Name" <email@domain.com>. The adapter handles this case, but make sure the domain in the email address matches a verified domain in Sweego.

Resources