Topics
A topic is a subscription category inside an audience. Topics let someone drop one kind of email without unsubscribing from everything, which keeps a list healthy: a reader who only wanted release notes can say so instead of leaving.
Each topic has a default, so contacts are subscribed or not without needing an explicit choice. Explicit choices are then stored as deviations from that default.
The Topic object
{
"id": "top_789k4m2v0dz1",
"object": "topic",
"name": "Product updates",
"description": "Release notes and changelogs",
"default_subscribed": true,
"created_at": "2026-02-20T09:00:00.000Z",
"updated_at": "2026-02-20T09:00:00.000Z"
}| Field | Notes |
|---|---|
name | Shown to subscribers on the preferences page. |
description | Optional. Shown alongside the name. |
default_subscribed | Whether a contact with no explicit choice is in. |
List topics
/v1/audiences/{audience_id}/topicsCreate a topic
/v1/audiences/{audience_id}/topics| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | |
description | string | No | |
default_subscribed | boolean | No | Defaults to true. |
curl -X POST https://go.day3.app/api/v1/audiences/aud_123/topics \
-H "Authorization: Bearer $DAY3_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Product updates",
"description": "Release notes and changelogs",
"default_subscribed": true
}'Think about default_subscribed before creating a topic. Setting it to true
opts your whole existing audience in, including people who never asked for this
category. That is defensible for a topic that describes mail you already send,
and not defensible for a new promotional stream.
Retrieve a topic
/v1/audiences/{audience_id}/topics/{topic_id}Update a topic
/v1/audiences/{audience_id}/topics/{topic_id}name, description and default_subscribed.
Changing default_subscribed affects only contacts with no explicit choice.
Anyone who has actively opted in or out keeps their choice.
Delete a topic
/v1/audiences/{audience_id}/topics/{topic_id}Removes the topic and every per-contact subscription attached to it. Contacts themselves are untouched.
{ "id": "top_789k4m2v0dz1", "deleted": true }Per-contact subscriptions
The read and write endpoints for one contact’s topics live on the contact:
GET /v1/audiences/{audience_id}/contacts/{id_or_email}/topicsPATCH /v1/audiences/{audience_id}/contacts/{id_or_email}/topics
The GET returns effective state, with explicit rows overlaid on defaults,
and an is_default flag telling you which is which. The PATCH takes a partial
map, so topics you leave out are untouched:
{ "topics": { "top_789": false, "top_790": true } }Full detail on Contacts.
You can also set topics per row inside a batch import, using the same map shape on each item, which is how a Mailchimp group or interest migration carries across in one pass.