Configure the Novu email channel by connecting a provider like SendGrid, Postmark, Mailgun, Amazon SES, or Resend to deliver transactional emails.
Email providers are the services that deliver notifications to your subscribers’ email. You must set up each provider individually in the Novu dashboard to enable delivery through the Email channel.Novu provides a unified integration layer that connects your workflows to these email providers. Once you’ve added your integrations, Novu handles routing and delivery automatically, sending each email through the correct provider without requiring additional setup. This allows you to manage multiple email integrations and switch providers when needed.
Multi-provider support: Integrate any major provider like SendGrid, SES, or Mailgun.
Failover mechanisms: Automatically retry with a backup provider to ensure reliability.
Activity tracking: Track delivery status, open rates, and more in the Novu dashboard. See Activity Tracking.
Email Activity Tracking is available on Novu Cloud and Enterprise self-hosted only. It is not included in Community self-hosted edition. See Activity Tracking for more information.
Start by adding an email provider in the Integration Store on your Novu dashboard. You can connect one or more integrations for different or the same providers.To learn how to add an email provider, refer to the guide for the supported providers.
Within the Email step, you can design your message using the built-in visual editor or code editor. Novu supports dynamic data from your payload, so each message can be personalized for the subscriber.
Novu automatically sends the notification to the email address stored on the subscriber’s profile. This profile is update either using the Novu dashboard or API.
When you add an email provider in the Integration Store, you configure settings that are common to all email providers, as well as credentials specific to that provider.
Novu asks for two default settings for any email provider you connect:
Sender name: The name that appears in the recipient’s “From” field.
From email address: The email address the notification is sent from. For some email providers, including SendGrid, you must authenticate the From email address to make sure you’re sending an email from an authorized address.
These are the default values used for every email sent via this integration. You can override them when triggering a workflow if needed.
You can control advanced email features at runtime by passing data in your trigger call. This lets you send attachments, override default settings, or target a specific provider for a single notification.
You can send attachments by passing an attachments array in the payload of your trigger. The attachment file can be provided as a buffer or a base64 encoded string.There is a total limit of 20MB for all attachments included in an email.
Node.js
Python
Go
PHP
.NET
Java
cURL
import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co",});await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", }, payload: { attachments: [ { // buffer format file: fs.readFileSync(__dirname + '/data/novu.jpeg'), name: 'novu.jpeg', mime: 'image/jpeg', }, { // base64 format file: 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC', name: 'blue.png', mime: 'image/png', } ], },});
You can override the email settings for a single trigger by passing an overrides object. This lets you override the following fields:
bcc
cc
from address
replyTo
replaceToRecipient
senderName
text
to address
Node.js
Python
Go
PHP
.NET
Java
cURL
import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co",});await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", }, overrides: { email: { to: ['to@novu.co'], from: 'from@novu.co', senderName: 'Novu Team', text: 'text version of email using overrides', replyTo: 'no-reply@novu.co', cc: ['1@novu.co'], bcc: ['2@novu.co'], }, },});
import osimport novu_pyfrom novu_py import Novuwith Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu: novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto( workflow_id="workflowId", to={"subscriber_id": "subscriberId"}, overrides={ "email": { "to": ["to@novu.co"], "from": "from@novu.co", "senderName": "Novu Team", "text": "text version of email using overrides", "replyTo": "no-reply@novu.co", "cc": ["1@novu.co"], "bcc": ["2@novu.co"], }, }, ))
By default, Novu uses your primary email provider. However, if you want to bypass this and force a specific, active integration for a trigger, use the integrationIdentifier.This is useful if you have multiple active integrations for different purposes. For example, you might have one integration for transactional emails and one for marketing emails. You can find the integrationIdentifier for each provider in provider page in the Integration Store.
Node.js
Python
Go
PHP
.NET
Java
cURL
import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co",});await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", }, overrides: { email: { integrationIdentifier: "brevo-abcdef" }, },});
Each Novu environment can have multiple layouts. Each email step in the workflow can have a layout assigned to it. Overriding the email layout allows you to dynamically override layout settings at trigger time, providing flexible layout management per workflow/channel or per step execution.layoutId values and its behavior:
Value
Behavior
”layout-identifier”
Uses layout with this identifier
”507f1f77bcf86cd799439011”
Uses layout with this MongoDB ObjectId
null
Explicitly no layout - renders email without any layout
undefined
Default behavior - uses step’s configured layout or environment default
Not specified
Same as undefined
Precedence rules:
Step-level override - Highest priority
Workflow-level/channels-level override
Step configuration (configured in workflow editor)
Environment default layout - Lowest priority
Node.js
Python
Go
PHP
.NET
Java
cURL
import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co",});await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", }, payload: {}, overrides: { // Channel-level layouts channels: { email: { layoutId: 'black-friday-layout', }, }, steps: { 'welcome-email': { // This email step uses a specific welcome layout layoutId: 'welcome-v2' }, 'promotional-email': { // This email uses the channel-level layout (black-friday-layout) // No layoutId specified = inherits from channel level }, 'transactional-receipt': { // This email explicitly uses no layout (plain email) layoutId: null } } }});
You can send provider specific extra fields by passing a _passthrough object in the overrides object. This lets you send extra fields to the provider SDK. Novu internally uses provider’s official SDK to send the email. Each provider has its own supported extra fields. Those extra fields are not validated by Novu and are passed directly to the provider SDK. There are three type of fields that you can send: body, headers, and query. Below is an example of sending tags supported by Resend provider.
Node.js
Python
Go
PHP
.NET
Java
cURL
import { Novu } from '@novu/api';const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co",});await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", }, payload: {}, overrides: { providers: { resend: { _passthrough: { body: { tags: [ { name: "category", value: "confirm_email" } ] }, headers: { "X-Custom-Header": "custom-header-value" }, query: { "queryParam": "queryValue" } } } } }});
By default, Novu does not add any unsubscribe links to the email. Few providers add unsubscribe links to the email by default. If you are looking to add custom unsubscribe links to the email, follow below steps:
Add {{payload.unsubscribeEmail}} field in the email editor.
Build custom unsubscribe link in your application using subscriberId workflowId. Make sure this link is secured with tokens to prevent abuse.
Use Novu preference api to update the email channel preferences for this workflow to false.
Optionally, you can build a custom unsubscribe page and add the link of that page for unsubscribe email option.
Send the value of unsubscribeEmail variable in the payload while triggering the workflow.
Novu will add the unsubscribe link to the email and end user will be able to unsubscribe from the email by clicking on the link.
Novu supports inbound email replies — not only sending mail through your email provider. The replyTo override above sets where replies are addressed when sending; to process replies, choose one of these paths: