# Contexts - Novu Changelog

> Novu changelog: Contexts. Learn about the latest updates, features, and improvements to the Novu notification infrastructure platform.

Canonical: https://novu.co/changelog/contexts-structure-and-scope-for-your-notifications/

Markdown: https://novu.co/changelog/contexts-structure-and-scope-for-your-notifications.md

Last updated: 2025-11-10T13:14:00.000Z

Define tenant, app, or workspace context once, and Novu automatically scopes every notification, Inbox feed, preference, and delivery path to that context. No duplicated workflows, no custom filters, and no risk of cross-tenant leaks.

Published: 2025-11-10T13:14:00.000Z

Categories: Infrastructure

> [!NOTE] Early Access
>
> This feature is currently in beta. If you'd like to access Contexts, please email our support team at support@novu.co

A **Context** in Novu is a structured object that describes the environment or scope to which a notification belongs. Instead of embedding metadata (like tenant ID or app name) into every trigger payload, you can now store it once and reference it everywhere.

| Property | Description | Example |
| --- | --- | --- |
| type | Category key (e.g. tenant, app, region) | "tenant" |
| id | Unique identifier within that type | "org-acme" |
| data | JSON object with custom metadata | { "name": "Acme Corp", "plan": "enterprise" } |
| key | Unique composite identifier | "tenant:org-acme" |

### **Context object schema**

When defining contexts, Novu supports multiple formats per key-value pair, allowing you to store and reference metadata relevant to your workflows and templates.

```javascript
await novu.trigger('welcome-email', {
  to: 'user123',
  payload: { userName: 'John' },
  context: {
    // Simple string format
    tenant: 'acme-corp',

    // Rich object format (ID only)
    app: { id: 'jira' },

    // Rich object format (ID + data)
    region: {
      id: 'us-east',
      data: {
        name: 'US East',
        timezone: 'America/New_York',
        currency: 'USD'
      }
    }
  }
});
```

### **How it works**

#### **1. Create reusable contexts**

```json
POST /v2/contexts

{
  "type": "tenant",
  "id": "org-acme",
  "data": { "name": "Acme Corp", "plan": "enterprise" }
}
```

**Contexts** are stored with unique environment and organization indexes, ensuring clean separation across projects.

#### **2. Reference them in workflow triggers**

```javascript
await novu.trigger('payment-success', {
  to: 'user-123',
  payload: { amount: '$250' },
  context: {
    tenant: 'org-acme',
    app: { id: 'jira', data: { name: 'Jira Integration' } },
  },
});

```

- Contexts can be passed as **simple strings** or **rich objects**.

- Missing contexts are created automatically.

- All related notifications, messages, and jobs store the context keys for traceability.

#### **3. Resolved automatically at runtime**

During message delivery, the worker reconstructs the context from its stored key(s), exposing all context data in your templates:

```javascript
{{context.tenant.data.name}}   →   Acme Corp
{{context.app.id}}   →.  jira
```

#### **4. Manage through API or Dashboard**

- **GET /v2/contexts/:type/:id** — retrieve

- **PATCH /v2/contexts/:type/:id** — update data

- **GET /v2/contexts** — list & search

- **DELETE /v2/contexts/:type/:id** — remove

[Visit the documentation to learn how to create, update, and retrieve a Context.](<https://docs.novu.co/platform/workflow/contexts/manage-contexts#create-a-context>)

### &lt;Inbox /&gt; with Contexts

> [!NOTE] Note
>
> Requires &lt;Inbox /&gt; version 3.11.0 or higher

As products mature, they typically shift from serving a single user group to supporting multiple groups.

Each **organization**, **environment**, or **workspace** has its own unique data, brand, and set of rules.

Most notification systems regard users as a single group with the same feeds, which leads teams to create weak filters and have duplicate subscribers across different tenants.

This is where **&lt;Inbox /&gt; with Contexts** excels for managing multi-tenancy. It offers built-in support directly at the notification layer, providing each tenant with a dedicated Inbox setup. This approach keeps your subscriber model and workflows intact without requiring any duplication.

#### Inbox Scoped by Context

When you render the Inbox, merely pass the same context:

The &lt;Inbox /&gt; knows precisely which messages to load, filtered by context.

Subscribers can switch between tenants or workspaces. Each one shows its own separate feed and settings.

- Inbox A → `tenant:org-acme`

- Inbox B → `tenant:org-globex`

- Inbox C → `tenant:org-novu`

Each has its own unread counts, archived messages, and rules. They all use a single subscriber ID (`user-123`).

```javascript
<Inbox
  applicationIdentifier="YOUR_APP_ID"
  subscriberId="YOUR_SUBSCRIBER_ID"
  context={{ tenant: 'acme', app: 'dashboard' }}
  contextHash="CONTEXT_HASH_VALUE"
/>
```

[Learn how to use contexts in the Inbox component to filter and personalize notifications for your subscribers](<https://docs.novu.co/platform/inbox/configuration/inbox-with-context>)

### Improvements (2)

- **feat(dashboard,api-service, worker)**: include inbox unread count in the FCM and Expo messages available on the app badge

- **feat(worker)**: device token invalidation logic for FCM and Expo is now enabled, in active tokens will be removed and notified via the message.failed webhook

### Fixes (4)

- **fix(api-service,application-generic)**: Passing null values when updating subscriber will now properly recognize and persist them

- **fix(api-service)**: translation keys escaping bug caused \\"\\ fields when used escaped fields in the i18n files

- **fix(js)**: notification count display for 99+ was properly fixed, where previously 100 was shown.

### New Providers (1)

- [iSendPro](<https://en.isendpro.com/>) - SMS Provider
