docs/guides/use-cases/digest-notifications.mdx
Batch related notifications into a single digest message using Novu's digest step. Instead of sending one notification per event, Novu collects events over a time window and delivers a summarized message such as "10 people liked your post."
Add a digest step to your workflow before the channel step. Novu collects events that match the digest key within the configured window, then renders a single notification with aggregated content.
Typical digest settings:
payload.postId to group events| Scenario | Digest window | Example message |
|---|---|---|
| Social activity | 1–24 hours | "10 people liked your post" |
| Weekly summary | 7 days | "Your weekly activity report" |
| Comment threads | 15–60 minutes | "5 new replies on your thread" |
Trigger the same workflow for each individual event. Novu handles batching automatically based on the digest step configuration and digest key.
<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api';const novu = new Novu({ secretKey: process.env.NOVU_SECRET_KEY });
await novu.trigger({ workflowId: 'post-liked', to: { subscriberId: 'user_123' }, payload: { postId: 'post_456', likerName: 'Alex' }, });
</Tab>
<Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu
with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
workflow_id="post-liked",
to={"subscriber_id": "user_123"},
payload={"postId": "post_456", "likerName": "Alex"},
))
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"
)
s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))
_, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "post-liked", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "user_123", }), Payload: map[string]any{ "postId": "post_456", "likerName": "Alex", }, }, nil)
</Tab>
<Tab title="PHP">
```php
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()
->setSecurity('<YOUR_SECRET_KEY_HERE>')
->build();
$sdk->trigger(
triggerEventRequestDto: new Components\TriggerEventRequestDto(
workflowId: 'post-liked',
to: new Components\SubscriberPayloadDto(subscriberId: 'user_123'),
payload: [
'postId' => 'post_456',
'likerName' => 'Alex',
],
),
);
var sdk = new NovuSDK(secretKey: "<YOUR_SECRET_KEY_HERE>");
await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "post-liked", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "user_123", }), Payload = new Dictionary<string, object>() { { "postId", "post_456" }, { "likerName", "Alex" }, }, });
</Tab>
<Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
import java.util.Map;
Novu novu = Novu.builder()
.secretKey("<YOUR_SECRET_KEY_HERE>")
.build();
novu.trigger()
.body(TriggerEventRequestDto.builder()
.workflowId("post-liked")
.to(To2.of(SubscriberPayloadDto.builder()
.subscriberId("user_123")
.build()))
.payload(Map.ofEntries(
Map.entry("postId", "post_456"),
Map.entry("likerName", "Alex")))
.build())
.call();