# Topics in Novu (/platform/concepts/topics)

Learn how topics work in Novu and how they help you organize and target groups of subscribers efficiently.

In Novu, a *topic* is a way to group subscribers under a shared label so that you can broadcast a message to many users with a single workflow trigger. This fan-out mechanism removes the need to manage individual subscriber IDs for each notification, streamlining scenarios like product announcements, feature rollouts, or status updates.

## Topics identifiers

Each topic is uniquely identified by a topic key, a permanent, internal reference in your system. You can also assign a name to help describe its purpose, for example, "Task Updates" or "Comment Thread Subscribers".

The `topicKey` must be unique and cannot be changed after creation; Novu enforces this uniqueness behind the scenes. Example: `task:taskId` or `post:postId`.

Common use cases for topics:

* Notifying all members of a specific team or project
* Messaging users who commented on a post
* Updating subscribers to a specific product or feature

## How topics fit into Novu's model

Novu’s notification system is built around workflows, which are triggered for one or more recipients. Topics act as a special type of recipient, representing a group of subscribers instead of an individual.

When you trigger a workflow using a topic:

* The `to` field accepts the topic’s key.
* Novu looks up all subscribers assigned to the topic.
* A separate workflow event is created for each subscriber.

Topics let you target large groups with a single API call, removing the need to loop through subscribers or send multiple workflow triggers.

<Callout>Topics don’t replace individual targeting. You can still trigger workflows for specific subscribers or arrays of subscribers when needed.</Callout>

## Dynamic and decoupled grouping

Once a topic is created, you can assign or remove subscribers at any time. Subscribers don’t need to know they belong to a topic, and it doesn’t affect their personal notification preferences.

Topics are dynamic and reflect real-time states. For example, a topic might include:

* Users who are currently watching a post
* Team members assigned to a project

This makes topics especially useful for modeling dynamic relationships in your application.

## Scalability and limits

Topics are designed for high-volume, high-efficiency use cases:

* Each topic supports up to 100,000 subscribers.
* A separate workflow event is created for each subscriber when a workflow is triggered to the topic

## Autogenerated topics

Novu supports on-the-fly topic creation. If you attempt to add subscribers to a topic key that doesn't exist for the selected environment and organization, Novu will automatically create a new topic named `Autogenerated-<TOPIC_KEY>` and assign the subscribers to it. This auto-generated topic can then be renamed and managed just like any other topic created manually.

<Callout type="info">
  Topics can be managed from [Novu dashboard](https://dashboard.novu.co/topics) or using [Topics APIs](/api-reference/topics/topic-schema)
</Callout>

## Trigger workflow

As mentioned above, a workflow can be triggered to a topic in the same way as it is triggered to subscribers.

### To a single topic

To trigger a workflow to a topic, use `to` field with type `Topic` and topicKey.

<Tabs items={["Node.js", "cURL"]}>
  <Tab value="Node.js">
    ```ts
    import { Novu } from "@novu/api"

    const novu = new Novu({ secretKey: "<YOUR_SECRET_KEY_HERE>", });

    await novu.trigger({
      to: { type: "Topic", topicKey: "topic_key" },
      workflowId: "workflow_identifier",
    });
    ```
  </Tab>

  <Tab value="cURL">
    ```bash
    curl -L -g -X POST 'https://api.novu.co/v1/events/trigger' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: ApiKey <NOVU_SECRET_KEY>' \
    -d '{
        "name": "workflow_identifier",
        "to": {
            "type": "Topic",
            "topicKey": "topic_key"
        }
    }'
    ```
  </Tab>
</Tabs>

### To multiple topics

`to` field also accepts array of topics. This is useful when you want to trigger a workflow to multiple topics at once.

<Tabs items={["Node.js", "cURL"]}>
  <Tab value="Node.js">
    ```ts
    import { Novu } from "@novu/api"

    const novu = new Novu({ secretKey: "<YOUR_SECRET_KEY_HERE>", });

    await novu.trigger({
      to: [
        { type: "Topic", topicKey: "topic_key_1" }, 
        { type: "Topic", topicKey: "topic_key_2" }
      ],
      workflowId: "workflow_identifier",
    });
    ```
  </Tab>

  <Tab value="cURL">
    ```bash
    curl -L -g -X POST 'https://api.novu.co/v1/events/trigger' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: ApiKey <NOVU_SECRET_KEY>' \
    -d '{
        "name": "workflow_identifier",
        "to": [
          {
              "type": "Topic",
              "topicKey": "topic_key_1"
          },
          {
              "type": "Topic",
              "topicKey": "topic_key_2"
          }
        ]
    }'
    ```
  </Tab>
</Tabs>

### Exclude actor

When a workflow is triggered to a topic, notification is sent to all subscribers present in the topic. However, you can exclude a specific subscriber from receiving the notification by using the `actor` field. Here actor is the subscriberId of the subscriber you want to exclude.

<Tabs items={["Node.js", "cURL"]}>
  <Tab value="Node.js">
    ```ts
    import { Novu } from "@novu/api"

    const novu = new Novu({ secretKey: "<YOUR_SECRET_KEY_HERE>", });

    await novu.trigger({
      to: [{ type: "Topic", topicKey: "topic_key_1" }],
      workflowId: "workflow_identifier",
      actor: "actor_subscriber_Id"
    });
    ```
  </Tab>

  <Tab value="cURL">
    ```bash
    curl -L -g -X POST 'https://api.novu.co/v1/events/trigger' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: ApiKey <NOVU_SECRET_KEY>' \
    -d '{
        "name": "workflow_identifier",
        "to": [
          {
              "type": "Topic",
              "topicKey": "topic_key_1"
          }
        ],
        "actor": "actor_subscriber_Id"
    }'
    ```
  </Tab>
</Tabs>

## Explore the topics APIs

These are commonly used topics APIs. Explore all topics APIs on topics [api reference page](/api-reference/topics/topic-schema).

<Cards>
  <Card title="Create a topic API" href="/api-reference/topics/create-a-topic" description="Create a new topic with name and topicKey" />

  <Card title="Update a topic API" href="/api-reference/topics/update-a-topic" description="Update existing topic using topicKey" />

  <Card title="Create topic subscription API" href="/api-reference/topics/create-topic-subscriptions" description="Add multiple subscribers into a topic" />

  <Card title="List topic subscriptions API" href="/api-reference/topics/list-topic-subscriptions" description="List all subscribers present in a single topic" />

  <Card title="List all topics API" href="/api-reference/topics/list-all-topics" description="List all topics in an environment" />

  <Card title="Check subscriber subscription API" href="/api-reference/topics/check-topic-subscriber" description="Check if a subscriber is present in a topic" />
</Cards>

## Frequently asked questions

Below are some of the most frequently asked questions about topics:

### Do topics override subscriber preferences?

No. Topics only define delivery groups. Each subscriber’s individual notification preferences remain intact.

### Is a topic like a mailing list?

Conceptually, yes. Topics group users to receive shared messages. However, topics are more dynamic and integrated into your application logic.

### Can a subscriber belong to multiple topics?

Yes. Subscribers can be members of any number of topics. This allows overlapping targeting strategies (for example, `task-updates`, `project-X`, and `admin-notifications`).

### Can I reuse the same topic key across environments?

Topic keys must be unique within each [environment](/platform/developer/environments). You can reuse the same key (for example, `feature-release`) in different environments like staging and production.

### What happens if I trigger a workflow to a topic with no subscribers?

The workflow is processed, but no notifications are delivered and, hence, this trigger is not counted for billing.
