Subscription Topics

Let subscribers manage category preferences instead of all-or-nothing unsubscribe. Topics enable granular subscription management so users can opt out of specific email categories while staying subscribed to others.

Overview

Without topics, unsubscribing removes a subscriber from all emails. With topics, subscribers see a preferences page where they can choose which categories they want to receive. This reduces full unsubscribes and improves engagement.

Default behavior: Subscribers are subscribed to all topics by default. Only when a subscriber explicitly unsubscribes from a topic are they excluded. No TopicSubscription record means "subscribed".

Create a Topic

POST /v1/topics

Request Body

ParameterTypeDescription
namestringTopic name (required, max 100 chars)
descriptionstringTopic description shown on preferences page (max 500 chars)
isDefaultbooleanWhether this is a default topic (default: false)
sortOrdernumberDisplay order on preferences page (default: 0)

Example

const topic = await client.topics.create({
  name: 'Weekly Digest',
  description: 'Our weekly newsletter with top stories and updates',
});

// Create multiple topics
await client.topics.create({
  name: 'Product Updates',
  description: 'New features, improvements, and release notes',
  sortOrder: 1,
});

await client.topics.create({
  name: 'Promotions',
  description: 'Special offers, discounts, and deals',
  sortOrder: 2,
});

List Topics

GET /v1/topics

Query Parameters

ParameterTypeDescription
activebooleanFilter by active status
const { data: topics } = await client.topics.list();
// [{ id, name, slug, description, active, subscriberCount, ... }]

// List only active topics
const { data: activeTopics } = await client.topics.list({ active: true });

Update & Delete Topics

PATCH /v1/topics/:id
DELETE /v1/topics/:id

Deleting a topic performs a soft delete (sets active: false). The topic and its subscription data are preserved.

// Update a topic
await client.topics.update('topic_xxx', {
  description: 'Updated description',
  sortOrder: 3,
});

// Deactivate a topic (soft delete)
await client.topics.delete('topic_xxx');

// Reactivate a topic
await client.topics.update('topic_xxx', { active: true });

Sending Emails with Topics

When sending emails via the API, you can optionally specify a topicId. This associates the email with a topic for tracking purposes.

await client.emails.send({
  from: 'newsletter@yourdomain.com',
  to: 'user@example.com',
  subject: 'Weekly Digest #42',
  html: '<h1>This week in review...</h1>',
  topicId: 'topic_weekly_digest',
});

For campaigns, the topic is checked during send. Subscribers who have unsubscribed from the campaign's topic will be automatically skipped.

Subscriber Preferences

Manage per-subscriber topic preferences programmatically.

GET /v1/audiences/:audienceId/subscribers/:subscriberId/topics
PUT /v1/audiences/:audienceId/subscribers/:subscriberId/topics

Get Preferences

const { data: preferences } = await client.topics.getPreferences(
  'aud_xxx',
  'sub_xxx'
);

// [
//   { topicId: 'xxx', topicName: 'Weekly Digest', subscribed: true },
//   { topicId: 'yyy', topicName: 'Promotions', subscribed: false },
// ]

Set Preferences

await client.topics.setPreferences('aud_xxx', 'sub_xxx', {
  topics: [
    { topicId: 'topic_weekly', subscribed: true },
    { topicId: 'topic_promos', subscribed: false },
  ],
});

Unsubscribe Flow

When topics are configured and a subscriber clicks an unsubscribe link in a campaign email, they see a preferences page instead of the standard "unsubscribe from all" confirmation. This page shows checkboxes for each active topic, letting subscribers opt out of specific categories while staying subscribed to others.

Preferences Page Behavior

  • Topics configured: Subscriber sees topic checkboxes + "Unsubscribe from all" option
  • No topics: Subscriber sees simple "Yes, unsubscribe me" confirmation
  • Default state: All topics are checked (subscribed) by default

Required Scopes

EndpointScope
List / Get topicstopic:read
Create / Update / Delete topicstopic:write
Get subscriber preferencesaudience:read
Set subscriber preferencesaudience:write