Meridian handbook
ReferenceConfiguration

engine.yaml: mail and newsletter

Every key of engine.yaml's mail section (the transactional mail driver for SMTP, Postmark, Amazon SES or Resend, bounce webhooks, templates, suppression and broadcast sending) and its newsletter section, with type, default and meaning.

The engine sends mail through a provider or relay you bring; it never runs mail infrastructure. Transactional mail (sign-in links, enquiry notifications, confirmations) uses the mail section. The Newsletter module’s campaigns use the same driver with the newsletter section’s sender and rules.

mail:
  driver: postmark
  from: "Visit Example <hello@example.org>"
  reply_to: help@example.org
  postmark:
    server_token: ${POSTMARK_SERVER_TOKEN}
    webhook_token: ${POSTMARK_WEBHOOK_TOKEN}

Check a configuration with a real send:

engine-dmo mail status
engine-dmo mail test --to you@example.org            # sends the magic-link template by default

mail

KeyTypeDefaultMeaning
mail.driverstringEmpty (log)postmark, ses, resend, smtp, or log (messages are written to the log, development only). engine-dmo check refuses log in production
mail.fromstringEmptyThe sender, hello@example.org or Visit Example <hello@example.org>. Required in production
mail.reply_tostringEmptyThe Reply-To address
mail.rate_limit_per_minuteinteger0The most messages a minute each process sends; 0 is no limit
mail.delivery_record_retentionretentionEmpty (13m)How long delivery records (what was sent to whom, and its outcome) are kept

mail.smtp

KeyTypeDefaultMeaning
mail.smtp.hoststringEmptyThe relay’s host. Required for a send
mail.smtp.portinteger0 (meaning 587)The relay’s port
mail.smtp.usernamestringEmptyThe user, when the relay needs authentication
mail.smtp.passwordsecretEmptyThe password
mail.smtp.tlsstringEmptystarttls: require STARTTLS; tls: connect over TLS from the start (port 465); none: never encrypt. Empty uses STARTTLS when the relay offers it. TLS 1.2 or later

Only Postmark, SES and Resend report bounces and complaints back through a webhook; an SMTP relay does not.

mail.postmark

KeyTypeDefaultMeaning
mail.postmark.server_tokensecretEmptyThe Postmark server’s API token
mail.postmark.message_streamstringEmptyThe transactional message stream; empty is Postmark’s default stream
mail.postmark.broadcast_streamstringEmpty (broadcast)The stream marketing mail (newsletters and broadcasts) goes out on, so its reputation stays apart
mail.postmark.webhook_tokensecretEmptyThe token Postmark’s bounce and complaint webhook must present. Required in production

mail.ses

KeyTypeDefaultMeaning
mail.ses.regionstringEmptyThe AWS region, such as eu-west-2
mail.ses.access_key_idstringEmptyThe IAM access key
mail.ses.secret_access_keysecretEmptyIts secret
mail.ses.configuration_setstringEmptyThe SES configuration set that publishes events
mail.ses.notification_topic_arnstringEmptyThe SNS topic bounces and complaints arrive from; notifications from another topic are refused

mail.resend

KeyTypeDefaultMeaning
mail.resend.api_keysecretEmptyThe Resend API key. Required in production
mail.resend.webhook_secretsecretEmptyThe signing secret of the webhook endpoint the Resend dashboard shows (whsec_...). Required in production

mail.webhooks

KeyTypeDefaultMeaning
mail.webhooks.pathstringEmpty (/_mail/webhooks)Where the provider posts delivery events. Only the configured driver’s route exists: <path>/postmark, <path>/ses or <path>/resend. Point the provider’s webhook at https://<your host><path>/<driver>

mail.templates

KeyTypeDefaultMeaning
mail.templates.dirstringEmpty (emails)The subdirectory, in each of a site’s template roots, that holds your mail templates (templates/_shared/emails/). A template there replaces the engine’s of the same name
mail.templates.plain_textstringEmpty (generate)generate makes the plain-text part from the HTML when a template has no .txt alternative; require makes a missing .txt an error

engine-dmo mail templates lists every transactional template, which directory resolved it, and whether a plain-text alternative exists.

mail.suppression

KeyTypeDefaultMeaning
mail.suppression.soft_bounce_thresholdinteger3Soft bounces within the window that suppress an address
mail.suppression.soft_bounce_windowretention30dThe window soft bounces are counted over
mail.suppression.notify_on_suppressbooleantrueWhen a CRM contact’s address is suppressed after a hard bounce, notify staff, naming the contact’s organisations (engine-dmo). The suppression is recorded on the contact’s timeline either way

mail.broadcast

How the CRM’s broadcasts to members are sent (engine-dmo).

KeyTypeDefaultMeaning
mail.broadcast.batch_sizeinteger50Messages queued at a time, 1 to 1000
mail.broadcast.batch_pauseduration5sThe pause between batches, 0s to 1h, on top of the mail rate limit
mail.broadcast.unsubscribe_footerbooleanUnset (on)Every broadcast carries an unsubscribe link. false is refused
mail.broadcast.open_trackingbooleanfalseCount opens with a tracking image
mail.broadcast.per_recipient_trackingbooleanfalseRecord clicks and opens per recipient rather than per broadcast; the footer then says so

newsletter

The Newsletter module’s sender and rules. Double opt-in is always on.

KeyTypeDefaultMeaning
newsletter.from_namestringEmptyThe sender name of campaigns. One line of plain text
newsletter.from_addressstringEmptyThe sender address, a bare address such as news@example.org
newsletter.reply_tostringEmptyThe reply address, a bare address
newsletter.double_opt_inbooleanUnset (on)false is refused: a subscriber always confirms
newsletter.pending_expiryretention14dAn unconfirmed subscriber is deleted after this, 1d to 90d
newsletter.preference_centre_pathstring/newsletter/preferencesThe preference centre’s path on each site: starting with /, not /_, no trailing slash
newsletter.open_trackingbooleanfalseCount opens
newsletter.click_trackingbooleanUnset (on)Send links through a counted redirect; false turns it off
newsletter.send_rate_per_minuteinteger600Campaign messages a minute, 1 to 100000
newsletter.dormant_afterretention12mAn active subscriber with no click in this long counts as dormant in the hygiene report. At least 30d
newsletter.require_domain_verificationbooleanUnset (on)A campaign is refused until the sending domain passes the SPF, DKIM and DMARC checks (engine-dmo newsletter deliverability)
newsletter.topicslist of strings[]The topics subscribers choose from, as lower case keys
newsletter.dkim_selectorslist of strings[]The DKIM selectors the deliverability check looks up for the sending domain

See Mail and Newsletters.