Appearance
Update a topic
Change a topic's name, description or visibility.
http
PATCH /v1/topics/{id}Requires a Full access API key.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The topic id. |
Body parameters
Send only the fields you want to change.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | The topic name. Max 120 characters. Renaming does not change the key. |
description | string | null | No | Max 255 characters. Send null to clear it. |
visibility | string | No | public or private. |
key and default_subscription are immutable and rejected if sent — see below.
Example
bash
curl -X PATCH "https://api.sendgrail.com/v1/topics/$TOPIC_ID" \
-H "Authorization: Bearer $SENDGRAIL_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Product news",
"visibility": "private"
}'js
const res = await fetch(`https://api.sendgrail.com/v1/topics/${id}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.SENDGRAIL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Product news',
visibility: 'private',
}),
});
const topic = await res.json();Response
json
{
"object": "topic",
"id": "7b2e6f90-3c11-4a5d-9b8e-1f0c4d6a2e59"
}Fetch the updated object with Retrieve a topic.
Note that key is still product-updates after the rename. The key is generated once, from the name the topic had at creation, and then it stands on its own.
The key cannot be changed
key is what identifies the topic in an unsubscribe link — and those links are already sitting in inboxes, in mail you sent last month and cannot recall. Changing the key would break every one of them: a contact clicking "unsubscribe from Product updates" would land on a topic that no longer answers to that name, and their opt-out would silently fail. So the key is fixed.
Send it anyway and it is rejected, not ignored:
json
{
"message": "The key cannot be changed — it is baked into unsubscribe links already sent.",
"code": "validation_error",
"errors": {
"key": ["The key cannot be changed — it is baked into unsubscribe links already sent."]
},
"request_id": "8f2c1e64-1b17-4f8c-9f0e-3b6c1e0f5c31"
}default_subscription cannot be changed either
default_subscription decides what a contact who never made a choice counts as: opt_out means they're in until they say otherwise, opt_in means they're out until they say so. Flipping it does not just change a setting — it changes the answer for every silent contact at once.
Turn opt_in into opt_out and you have just subscribed thousands of people who never asked to be. Turn opt_out into opt_in and you have unsubscribed thousands who never asked to leave. Neither is a change anyone can consent to after the fact, so SendGrail refuses to make it:
json
{
"message": "The default subscription cannot be changed after the topic is created.",
"code": "validation_error",
"errors": {
"default_subscription": ["The default subscription cannot be changed after the topic is created."]
},
"request_id": "8f2c1e64-1b17-4f8c-9f0e-3b6c1e0f5c31"
}A 200 here would be worse than a 422: you'd believe the default had changed when it hadn't, or worse, you'd have changed it without realising who it moved.
If you genuinely need a different default, create a new topic — accepting that it gets a new key, and that contacts start out with no choice recorded against it.
Changing visibility is safe
visibility is the one property that can move. A private topic is not offered on the public preference page unless the contact is already subscribed to it — useful for a category you enrol people in deliberately rather than advertising. Flipping between public and private changes what the preference page shows; it does not change anybody's subscription.
Changing subscriptions
This endpoint edits the topic, not who is on it. To subscribe or unsubscribe a contact, go through the contact:
http
PATCH /v1/contacts/{id}/topicsSee Contact topics.