A category contacts subscribe to, with a default for those who never chose.
Body
Body| Field | Type | Description |
|---|
name* | string | Up to 50 characters, unique among live topics. |
default_subscription* | string | opt_in or opt_out: what a contact with no explicit choice is treated as. Fixed after creation. |
description | string | Up to 200 characters, shown on the preference page. |
visibility | string | public lists the topic on every contact's preference page; private (the default) only for contacts already opted in. |
curl -X POST "https://api.rasket.com/topics" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0" \
-H "Content-Type: application/json" \
-d '{
"name": "Product updates",
"description": "What shipped this month.",
"default_subscription": "opt_in",
"visibility": "public"
}'
const response = await fetch("https://api.rasket.com/topics", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Product updates",
description: "What shipped this month.",
default_subscription: "opt_in",
visibility: "public"
}),
});
const { id } = await response.json();
import os
import requests
response = requests.post(
"https://api.rasket.com/topics",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
json={
"name": "Product updates",
"description": "What shipped this month.",
"default_subscription": "opt_in",
"visibility": "public"
},
)
id = response.json()["id"]
Response 201
{
"object": "topic",
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
- A live topic with the same name is
422 invalid_parameter. - A broadcast scoped to a topic goes only to contacts whose effective subscription to it is
opt_in.
Every live topic, newest first.
Query parameters
Query parameters| Field | Type | Description |
|---|
limit | integer | How many items to return, 1–100. Defaults to 20. |
after | string | Return the page that follows this item ID. Mutually exclusive with before. |
before | string | Return the page that precedes this item ID. Mutually exclusive with after. |
curl -X GET "https://api.rasket.com/topics" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0"
const response = await fetch("https://api.rasket.com/topics", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
},
});
const data = await response.json();
import os
import requests
response = requests.get(
"https://api.rasket.com/topics",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
)
print(response.json())
Response 200
{
"object": "list",
"has_more": false,
"data": [
{
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
"name": "Product updates",
"description": "What shipped this month.",
"default_subscription": "opt_in",
"visibility": "public",
"created_at": "2026-09-08T22:22:17.595Z"
}
]
}
One topic by ID.
Path parameters
Path parameters| Field | Type | Description |
|---|
id* | string | The topic's ID. |
curl -X GET "https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0"
const response = await fetch("https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
},
});
const { id } = await response.json();
import os
import requests
response = requests.get(
"https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
)
id = response.json()["id"]
Response 200
{
"object": "topic",
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
"name": "Product updates",
"description": "What shipped this month.",
"default_subscription": "opt_in",
"visibility": "public",
"created_at": "2026-09-08T22:22:17.595Z"
}
Change the name, description or visibility.
Path parameters
Path parameters| Field | Type | Description |
|---|
id* | string | The topic's ID. |
Body
Body| Field | Type | Description |
|---|
name | string | Up to 50 characters. |
description | string | null | null clears it. |
visibility | string | public or private. |
curl -X PATCH "https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0" \
-H "Content-Type: application/json" \
-d '{
"visibility": "private"
}'
const response = await fetch("https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
"Content-Type": "application/json",
},
body: JSON.stringify({
visibility: "private"
}),
});
const { id } = await response.json();
import os
import requests
response = requests.patch(
"https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
json={
"visibility": "private"
},
)
id = response.json()["id"]
Response 200
{
"object": "topic",
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
default_subscription cannot change: a body that carries it is 422 invalid_parameter. Changing it would silently resubscribe or unsubscribe everyone who never chose.
Retire the topic and free its name.
Path parameters
Path parameters| Field | Type | Description |
|---|
id* | string | The topic's ID. |
curl -X DELETE "https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0"
const response = await fetch("https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
},
});
const { id } = await response.json();
import os
import requests
response = requests.delete(
"https://api.rasket.com/topics/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
},
)
id = response.json()["id"]
Response 200
{
"object": "topic",
"id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
"deleted": true
}
- The topic is
404 from that moment. Emails and consent records that name it keep doing so.