# Topics API

> Manage subscriber topics through the Broadcast API. A topic reads a custom data field or a tag and decides which subscribers receive broadcasts and sequences sent to it.

Source: https://sendbroadcast.net/docs/api-topics

A topic is one kind of email subscribers opt in to or out of. Read [Subscriber Topics](https://sendbroadcast.net/docs/subscriber-topics) first: it explains how a topic's value is stored and what "no value" means.

## Required Permissions

Topics describe your subscribers' preferences, so they use the subscriber permissions:

- **Subscribers read**: list and get topics
- **Subscribers write**: create, update and delete topics

## Topic Object

```json
{
  "id": 3,
  "name": "Webinars",
  "description": "Invitations to our webinars",
  "storage": "custom_data",
  "custom_data_key": "sub_webinars",
  "tag_name": null,
  "unset_receives": false,
  "visible_on_preference_page": true,
  "position": 1,
  "created_at": "2026-10-06T12:00:00Z",
  "updated_at": "2026-10-06T12:00:00Z"
}
```

- `storage`: `custom_data` (the value is the top-level custom data key `custom_data_key`) or `tag` (the value is whether the subscriber has the tag `tag_name`).
- `unset_receives`: whether a subscriber with no value receives the topic. Read at send time; Broadcast never writes it into custom data. Must be `false` for a tag topic.
- `visible_on_preference_page`: whether subscribers can switch the topic themselves.
- `position`: the order on the preference page.

## List Topics

`GET /api/v1/topics`

```bash
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://your-broadcast-domain.com/api/v1/topics
```

```json
{ "data": [ { "id": 3, "name": "Webinars", "...": "..." } ], "total": 1 }
```

## Get Topic

`GET /api/v1/topics/:id`

## Create Topic

`POST /api/v1/topics`

```bash
curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data-raw '{
    "topic": {
      "name": "Webinars",
      "storage": "custom_data",
      "custom_data_key": "sub_webinars",
      "unset_receives": false
    }
  }' \
  https://your-broadcast-domain.com/api/v1/topics
```

For a tag topic, send `"storage": "tag"` and `"tag_name": "webinars"`. Returns `201` with the topic, or `422` with an `error` message.

## Update Topic

`PATCH /api/v1/topics/:id` with the fields to change inside `topic`.

## Delete Topic

`DELETE /api/v1/topics/:id`

Returns `422` while a broadcast or sequence uses the topic, so a send never widens to everyone it targets. Remove the topic from them first. Deleting a topic does not change any subscriber data.

## Topics on other resources

- **Subscribers**: the subscriber JSON has `topics`, each topic's stored value: `true`, `false`, or `null` for no value (a tag topic is `true` or `null`). To change topic values, update `custom_data` or the tags; with `"custom_data_mode": "merge"` only the keys you send change. See [Subscribers API](https://sendbroadcast.net/docs/api-subscribers).
- **Broadcasts and sequences**: send `topic_id` on create or update. See [Broadcasts API](https://sendbroadcast.net/docs/api-broadcasts) and [Sequences API](https://sendbroadcast.net/docs/api-sequences).
- **Webhooks**: `subscriber.preferences_updated` fires on every topic change. See [Webhooks](https://sendbroadcast.net/docs/webhooks).
