PayloadSolutions

Configuration

Every option of resendBroadcastsPlugin(), with its default.

resendBroadcastsPlugin({
  sources: [/* … */], // required
  from: 'Acme <[email protected]>',
})

Options

OptionDefaultWhat it does
sources—the subscriber collections; see below. At least one
apiKeyprocess.env.RESEND_API_KEYa full-access Resend API key
webhookSecretprocess.env.RESEND_WEBHOOK_SECRETthe signing secret of the unsubscribe webhook
from—"Name <address>" used when neither the campaign nor Newsletter Settings sets one. Must be on a verified domain
replyTo—reply-to used when neither the campaign nor Newsletter Settings sets one
templates{ default: DefaultTemplate }React Email templates by name; default is used unless a campaign picks another
variables—extra values the same for every subscriber, as an object or ({ payload }) => object. Usable in the subject too
editorthe plugin's email editora Lexical editor for the campaign body and the footer
media.collection—an upload collection; adds the Image block to the body and footer editors
media.baseUrlthe server URLpublic origin that relative (or server-URL) upload URLs are put on
media.allowPrivateUrlsfalseallow localhost and private-network image URLs in broadcasts — for development only
access.manageany logged-in userwho can read and edit lists, campaigns and settings, preview and test
access.sendaccess.managewho can send, schedule, cancel and resync
adminGroup'Newsletter'the admin nav group
slugsnewsletter-lists, newsletter-campaigns, newsletter-sync-runs, newsletter-settingsrename the plugin's collections and global
syncMode'await''background' syncs after the response instead of inside the save
deleteContactstruedelete a Resend contact when the last document with its address is deleted
resend.requestsPerSecond2throttle for every Resend call this process makes; 0 disables it
resend.baseUrlResend's APIanother API host — a mock in development and tests
resend.client—bring your own ResendClient (from createResendClient)
disabledfalsekeep the collections and fields, so the schema is stable, but make no call to Resend: no sync hooks, no endpoints

Sources

OptionDefaultWhat it does
collection—the collection slug
fields.email'email'path of the email field
fields.name'name'path of a full-name field, split on the first space. Not used when firstName or lastName is mapped
fields.firstName, fields.lastName—paths of separate name fields
fields.subscribed'subscribed'path of the opt-in checkbox
addFieldstrueadd email, name and subscribed when the collection lacks them (top-level paths only; never email on an auth collection)
defaultSubscribedfalsethe added checkbox's default for new documents
properties—{ key: { type, value, fallback?, description? } } pushed as Resend contact properties and usable as {{key}}
labelthe slughow the source reads in a list's Source select

Access

access.manage and access.send receive { req } and return a boolean (or a promise of one). They guard the collections, the global and every endpoint.

resendBroadcastsPlugin({
  access: {
    manage: ({ req }) => Boolean(req.user?.roles?.includes('editor') || req.user?.roles?.includes('admin')),
    send: ({ req }) => Boolean(req.user?.roles?.includes('admin')),
  },
  // …
})

Reading subscribers in the preview picker always uses the caller's own access on the source collection, whatever these return.

What the plugin adds to your config

AddedSlug
fields and afterChange/afterDelete hooks on every source collectionyour slugs
Lists collectionnewsletter-lists
Campaigns collection, with the Preview & send viewnewsletter-campaigns
Sync runs collectionnewsletter-sync-runs
Newsletter Settings globalnewsletter-settings
root endpoints/api/resend-broadcasts/webhook, /api/resend-broadcasts/resync
payload.resendBroadcastsattached in onInit

On this page