v1 · API reference

Topics

Subscription categories (e.g. Promotions) recipients can opt out of without leaving your list, independent of segment membership. Scope a campaign to a topic and opted-out contacts are skipped automatically.

Base URL: https://www.unitpost.com/api/v1/api/v1

Topics

List topics

GET/api/v1/api/v1/topics

GET /topics
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/topics' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "topic",
      "id": "id_123",
      "name": "Example",
      "description": "string",
      "default_opt_in": false,
      "created_at": "2026-01-01T00:00:00.000Z",
      "updated_at": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Retrieve a list of your subscription topics, cursor-paginated. A topic is a category of email (e.g. Product updates, Promotions) that recipients can opt out of without leaving your list entirely. Pass ?archived=true to list archived topics instead. Create one with Create a topic, or check a contact's preferences with List a contact's topic subscriptions. Requires the topics:read capability.

Parameters3 fields
FieldTypeDescription
limitinteger · queryMax rows to return (default 20, max 100).
afterstring · queryReturn rows after this id (forward paging).
beforestring · queryReturn rows before this id (backward paging).
Response · 200 fields7 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
namerequiredstring
descriptionrequiredobject
default_opt_inrequiredboolean
created_atrequiredstring
updated_atrequiredstring
200401422

Create a topic

POST/api/v1/api/v1/topics

POST /topics
curl -X POST 'https://www.unitpost.com/api/v1/api/v1/topics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Product updates",
    "default_subscribed": true
  }'
Response · 201
{
  "object": "topic",
  "id": "id_123",
  "name": "Example",
  "description": "string",
  "default_opt_in": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Create a subscription topic — a category recipients can opt out of on their own (e.g. Promotions) while staying on your list. default_opt_in decides whether contacts with no explicit preference are treated as subscribed. Scope a campaign to a topic so opted-out contacts are skipped automatically via Create a campaign, and set an individual contact's preference with Set a contact's topic preference. Topics differ from segments: a segment decides who a campaign targets, a topic lets recipients opt out. Requires the topics:write capability.

Request body3 fields
FieldTypeDescription
namerequiredstring
descriptionstring
default_opt_inboolean
Response · 201 fields7 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
namerequiredstring
descriptionrequiredobject
default_opt_inrequiredboolean
created_atrequiredstring
updated_atrequiredstring
201401409422

Retrieve a topic

GET/api/v1/api/v1/topics/{id}

GET /topics/{id}
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/topics/top_123' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "topic",
  "id": "id_123",
  "name": "Example",
  "description": "string",
  "default_opt_in": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Retrieve a single topic by id, including its name and default_opt_in setting. Change it with Update a topic, or list every topic with List topics. Requires the topics:read capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Response · 200 fields7 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
namerequiredstring
descriptionrequiredobject
default_opt_inrequiredboolean
created_atrequiredstring
updated_atrequiredstring
200401404

Update a topic

PATCH/api/v1/api/v1/topics/{id}

PATCH /topics/{id}
curl -X PATCH 'https://www.unitpost.com/api/v1/api/v1/topics/top_123' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ }'
Response · 200
{
  "object": "topic",
  "id": "id_123",
  "name": "Example",
  "description": "string",
  "default_opt_in": false,
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Update a topic's name or default_opt_in behavior, or pass { "archived": true | false } to archive or restore it. Archiving a topic hides it and stops it from being targeted, but is blocked with 409 while an active campaign still targets it. To manage a single contact's preference, use Set a contact's topic preference. Requires the topics:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Request body3 fields
FieldTypeDescription
namestring
descriptionobject
default_opt_inboolean
Response · 200 fields7 fields
FieldTypeDescription
objectrequiredstring
idrequiredstring
namerequiredstring
descriptionrequiredobject
default_opt_inrequiredboolean
created_atrequiredstring
updated_atrequiredstring
200401404409422

Delete a topic

DELETE/api/v1/api/v1/topics/{id}

DELETE /topics/{id}
curl -X DELETE 'https://www.unitpost.com/api/v1/api/v1/topics/top_123' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Archive a topic (a soft delete — existing subscription records are preserved so you can restore it later). It's blocked with 409 while an active campaign still targets it. Restore an archived topic by sending { "archived": false } to Update a topic. Requires the topics:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
204401404409

List a contact's topic subscriptions

GET/api/v1/api/v1/contacts/{id}/topics

GET /contacts/{id}/topics
curl -X GET 'https://www.unitpost.com/api/v1/api/v1/contacts/top_123/topics' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Response · 200
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "contact_topic",
      "topic_id": "topic_123",
      "subscribed": false,
      "status": "subscribed",
      "source": "user"
    }
  ]
}

Retrieve a contact's effective subscription state for every active topic, cursor-paginated. Each row resolves the contact's explicit preference against the topic's default_opt_in, so subscribed is always the answer to "would this contact receive a campaign scoped to this topic?". Change a preference with Set a contact's topic preference. Requires the topics:read capability.

Parameters4 fields
FieldTypeDescription
idrequiredstring · path
limitinteger · queryMax rows to return (default 20, max 100).
afterstring · queryReturn rows after this id (forward paging).
beforestring · queryReturn rows before this id (backward paging).
Response · 200 fields5 fields
FieldTypeDescription
objectrequiredstring
topic_idrequiredstring
subscribedrequiredboolean
statusrequiredenumsubscribed | unsubscribed
sourcerequiredenumuser | manual | import | api
200401404422

Set a contact's topic preference

POST/api/v1/api/v1/contacts/{id}/topics

POST /contacts/{id}/topics
curl -X POST 'https://www.unitpost.com/api/v1/api/v1/contacts/top_123/topics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "topic_id": "top_123",
    "subscribed": false
  }'
Response · 201
{
  "object": "contact_topic",
  "topic_id": "topic_123",
  "subscribed": false,
  "status": "subscribed",
  "source": "user"
}

Subscribe or unsubscribe a contact for one topic. This records an explicit preference that overrides the topic's default_opt_in, and it's idempotent — setting the same preference twice succeeds. PUT behaves identically. Read the contact's current state with List a contact's topic subscriptions. Requires the topics:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Request body3 fields
FieldTypeDescription
topic_idstring
topicstring
subscribedrequiredboolean
Response · 201 fields5 fields
FieldTypeDescription
objectrequiredstring
topic_idrequiredstring
subscribedrequiredboolean
statusrequiredenumsubscribed | unsubscribed
sourcerequiredenumuser | manual | import | api
201401404422

Set a contact's topic preference (alias of POST)

PUT/api/v1/api/v1/contacts/{id}/topics

PUT /contacts/{id}/topics
curl -X PUT 'https://www.unitpost.com/api/v1/api/v1/contacts/top_123/topics' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "topic_id": "top_123",
    "subscribed": false
  }'
Response · 201
{
  "object": "contact_topic",
  "topic_id": "topic_123",
  "subscribed": false,
  "status": "subscribed",
  "source": "user"
}

Identical to Set a contact's topic preference — provided so clients that prefer PUT semantics for an upsert can use it interchangeably. Requires the topics:write capability.

Parameters1 field
FieldTypeDescription
idrequiredstring · path
Request body3 fields
FieldTypeDescription
topic_idstring
topicstring
subscribedrequiredboolean
Response · 201 fields5 fields
FieldTypeDescription
objectrequiredstring
topic_idrequiredstring
subscribedrequiredboolean
statusrequiredenumsubscribed | unsubscribed
sourcerequiredenumuser | manual | import | api
201401404422