Email through ProductCraft Mail.
Notify decides who gets an email and when; Mail renders it, checks its suppression list and sends it from your verified domain.
Enable Mail in the same workspace and verify a sending domain with a default sender (see the Mail docs). Until then the email channel is skipped as channel_not_configured and the next fallback step runs.
1
A Mail template per type
Email HTML lives in Mail’s template editor, with its versions and previews. The type’s email template only names it, and optionally maps Mail’s variable names to yours. Mail receives the send’s data plus the recipient’s fields. The console’s type editor has a picker that shows the template’s variables and a rendered preview.
// The HTML lives in Mail (its template editor and versions). Notify passes
// the send's data plus recipient fields as the template's variables.
await notify.notificationTypes.replaceByKey("invoice.paid", {
name: "Invoice paid",
category_key: "billing",
routing: { always: ["inbox", "email"], fallback: [] },
templates: [
{ channel: "inbox", locale: "en", body: { title: "Invoice paid", body: "We received {{amount}}." } },
{
channel: "email",
locale: "en",
body: {
mail_template_name: "invoice-paid",
data_mapping: { total: "amount", link: "invoice_url" }, // Mail variable → Notify variable
},
},
],
});2
What protects your reputation
- Mail’s suppression list applies to every Notify email, critical ones included (
mail_suppressed). - A hard bounce stops email to that recipient until their address changes (
email_invalid). A spam complaint turns their email off for every non-critical type (email_complained). - The email budget keeps to Mail’s limits (60 a minute, 600 an hour, 10,000 a day): extra emails wait for the next window rather than failing.
- Automatic pause: if more than 0.1 % of the last 500 Notify emails were complaints, or more than 5 % hard bounces, email pauses for the workspace (critical ones too) and the owners are told. Fix the list, then resume.
- One-click unsubscribe on every non-transactional, non-critical email turns that category’s email off for that recipient.
const settings = await notify.settings.retrieve();
console.log(settings.email_enabled, settings.email_paused_at, settings.email_paused_reason);
// After fixing your list (an automatic pause): resume.
if (settings.email_paused_at) await notify.settings.update({ email_paused: false });3
Statuses
Email deliveries go sent when Mail accepts them, then delivered or bounced as the receiving server answers, so the message log shows the real outcome. The Mail message id is on the delivery. Testing? Send only to the Amazon SES mailbox simulator (success@simulator.amazonses.com) so test bounces never count against you: see testing.