Update a topic subscription
Update a subscription by its unique identifier for a topic. You can update the preferences and name associated with the subscription.
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.topics.subscriptions.update({
topicKey: "<value>",
identifier: "<value>",
updateTopicSubscriptionRequestDto: {
name: "My Subscription",
preferences: [
{
condition: {
"===": [
{
"var": "tier",
},
"premium",
],
},
workflowId: "workflow-123",
},
],
},
});
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
using System.Collections.Generic;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.Topics.Subscriptions.UpdateAsync(
topicKey: "<value>",
identifier: "<value>",
updateTopicSubscriptionRequestDto: new UpdateTopicSubscriptionRequestDto() {
Name = "My Subscription",
Preferences = new List<UpdateTopicSubscriptionRequestDtoPreferences>() {
UpdateTopicSubscriptionRequestDtoPreferences.CreateWorkflowPreferenceRequestDto(
new WorkflowPreferenceRequestDto() {
Condition = new Dictionary<string, object>() {
{ "===", new List<object>() {
new Dictionary<string, object>() {
{ "var", "tier" },
},
"premium",
} },
},
WorkflowId = "workflow-123",
}
),
},
}
);
// handle responsedeclare(strict_types=1);
require 'vendor/autoload.php';
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()
->setSecurity(
'YOUR_SECRET_KEY_HERE'
)
->build();
$updateTopicSubscriptionRequestDto = new Components\UpdateTopicSubscriptionRequestDto(
name: 'My Subscription',
preferences: [
new Components\WorkflowPreferenceRequestDto(
condition: [
'===' => [
[
'var' => 'tier',
],
'premium',
],
],
workflowId: 'workflow-123',
),
],
);
$response = $sdk->topics->subscriptions->update(
topicKey: '<value>',
identifier: '<value>',
updateTopicSubscriptionRequestDto: $updateTopicSubscriptionRequestDto
);
if ($response->subscriptionResponseDto !== null) {
// handle response
}from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.topics.subscriptions.update(topic_key="<value>", identifier="<value>", update_topic_subscription_request_dto={
"name": "My Subscription",
"preferences": [
{
"condition": {
"===": [
{
"var": "tier",
},
"premium",
],
},
"workflow_id": "workflow-123",
},
],
})
# Handle response
print(res)package main
import(
"context"
"github.com/novuhq/novu-go/v3"
"github.com/novuhq/novu-go/v3/models/components"
"log"
)
func main() {
ctx := context.Background()
s := v3.New(
v3.WithSecurity("YOUR_SECRET_KEY_HERE"),
)
res, err := s.Topics.Subscriptions.Update(ctx, "<value>", "<value>", components.UpdateTopicSubscriptionRequestDto{
Name: v3.Pointer("My Subscription"),
Preferences: []components.UpdateTopicSubscriptionRequestDtoPreferences{
components.CreateUpdateTopicSubscriptionRequestDtoPreferencesWorkflowPreferenceRequestDto(
components.WorkflowPreferenceRequestDto{
Condition: map[string]any{
"===": []any{
map[string]any{
"var": "tier",
},
"premium",
},
},
WorkflowID: "workflow-123",
},
),
},
}, nil)
if err != nil {
log.Fatal(err)
}
if res.SubscriptionResponseDto != nil {
// handle response
}
}curl --request PATCH \
--url https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "My Subscription",
"preferences": [
{
"workflowId": "workflow-123",
"condition": {
"===": [
{
"var": "tier"
},
"premium"
]
}
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'My Subscription',
preferences: [{workflowId: 'workflow-123', condition: {'===': [{var: 'tier'}, 'premium']}}]
})
};
fetch('https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.patch("https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"My Subscription\",\n \"preferences\": [\n {\n \"workflowId\": \"workflow-123\",\n \"condition\": {\n \"===\": [\n {\n \"var\": \"tier\"\n },\n \"premium\"\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"My Subscription\",\n \"preferences\": [\n {\n \"workflowId\": \"workflow-123\",\n \"condition\": {\n \"===\": [\n {\n \"var\": \"tier\"\n },\n \"premium\"\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"_id": "64f5e95d3d7946d80d0cb679",
"topic": {
"_id": "64f5e95d3d7946d80d0cb677",
"key": "product-updates",
"name": "Product Updates"
},
"subscriber": {
"_id": "64da692e9a94fb2e6449ad07",
"subscriberId": "user-123",
"avatar": "https://example.com/avatar.png",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]"
},
"createdAt": "2025-04-24T05:40:21Z",
"updatedAt": "2025-04-24T05:40:21Z",
"identifier": "tk=product-updates:si=subscriber-123",
"name": "My Subscription",
"preferences": [
{
"subscriptionId": "64f5e95d3d7946d80d0cb679",
"enabled": true,
"workflow": {
"id": "64a1b2c3d4e5f6g7h8i9j0k1",
"identifier": "welcome-email",
"name": "Welcome Email Workflow",
"critical": false,
"tags": [
"user-onboarding",
"email"
],
"data": {
"category": "onboarding",
"priority": "high"
}
},
"condition": {
"and": [
{
"===": [
{
"var": "tier"
},
"premium"
]
}
]
}
}
],
"contextKeys": [
"tenant:org-a",
"project:proj-123"
]
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"errors": {
"fieldName1": {
"messages": [
"Field is required",
"Must be a valid email address"
],
"value": "invalidEmail"
},
"fieldName2": {
"messages": [
"Must be at least 18 years old"
],
"value": 17
},
"fieldName3": {
"messages": [
"Must be a boolean value"
],
"value": true
},
"fieldName4": {
"messages": [
"Must be a valid object"
],
"value": {
"key": "value"
}
},
"fieldName5": {
"messages": [
"Field is missing"
],
"value": null
},
"fieldName6": {
"messages": [
"Undefined value"
]
}
},
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"API rate limit exceeded"{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"Please wait some time, then try again."Authorizations
API key authentication. Allowed headers-- "Authorization: ApiKey <novu_secret_key>".
Headers
A header for idempotency purposes
Path Parameters
The key identifier of the topic
The unique identifier of the subscription
Body
The name of the subscription
"My Subscription"
The preferences of the topic. Can be a simple workflow ID string, workflow preference object, or group filter object
[
{
"workflowId": "workflow-123",
"condition": { "===": [{ "var": "tier" }, "premium"] }
}
]
Response
OK
The unique identifier of the subscription
"64f5e95d3d7946d80d0cb679"
The topic information
Show child attributes
Show child attributes
The subscriber information
Show child attributes
Show child attributes
The creation date of the subscription
"2025-04-24T05:40:21Z"
The last update date of the subscription
"2025-04-24T05:40:21Z"
The identifier of the subscription
"tk=product-updates:si=subscriber-123"
The name of the subscription
"My Subscription"
The preferences for workflows in this subscription
Show child attributes
Show child attributes
Context keys that scope this subscription (e.g., tenant:org-a, project:proj-123)
["tenant:org-a", "project:proj-123"]
Was this page helpful?
import { Novu } from "@novu/api";
const novu = new Novu({
secretKey: "YOUR_SECRET_KEY_HERE",
});
async function run() {
const result = await novu.topics.subscriptions.update({
topicKey: "<value>",
identifier: "<value>",
updateTopicSubscriptionRequestDto: {
name: "My Subscription",
preferences: [
{
condition: {
"===": [
{
"var": "tier",
},
"premium",
],
},
workflowId: "workflow-123",
},
],
},
});
console.log(result);
}
run();using Novu;
using Novu.Models.Components;
using System.Collections.Generic;
var sdk = new NovuSDK(secretKey: "YOUR_SECRET_KEY_HERE");
var res = await sdk.Topics.Subscriptions.UpdateAsync(
topicKey: "<value>",
identifier: "<value>",
updateTopicSubscriptionRequestDto: new UpdateTopicSubscriptionRequestDto() {
Name = "My Subscription",
Preferences = new List<UpdateTopicSubscriptionRequestDtoPreferences>() {
UpdateTopicSubscriptionRequestDtoPreferences.CreateWorkflowPreferenceRequestDto(
new WorkflowPreferenceRequestDto() {
Condition = new Dictionary<string, object>() {
{ "===", new List<object>() {
new Dictionary<string, object>() {
{ "var", "tier" },
},
"premium",
} },
},
WorkflowId = "workflow-123",
}
),
},
}
);
// handle responsedeclare(strict_types=1);
require 'vendor/autoload.php';
use novu;
use novu\Models\Components;
$sdk = novu\Novu::builder()
->setSecurity(
'YOUR_SECRET_KEY_HERE'
)
->build();
$updateTopicSubscriptionRequestDto = new Components\UpdateTopicSubscriptionRequestDto(
name: 'My Subscription',
preferences: [
new Components\WorkflowPreferenceRequestDto(
condition: [
'===' => [
[
'var' => 'tier',
],
'premium',
],
],
workflowId: 'workflow-123',
),
],
);
$response = $sdk->topics->subscriptions->update(
topicKey: '<value>',
identifier: '<value>',
updateTopicSubscriptionRequestDto: $updateTopicSubscriptionRequestDto
);
if ($response->subscriptionResponseDto !== null) {
// handle response
}from novu_py import Novu
with Novu(
secret_key="YOUR_SECRET_KEY_HERE",
) as novu:
res = novu.topics.subscriptions.update(topic_key="<value>", identifier="<value>", update_topic_subscription_request_dto={
"name": "My Subscription",
"preferences": [
{
"condition": {
"===": [
{
"var": "tier",
},
"premium",
],
},
"workflow_id": "workflow-123",
},
],
})
# Handle response
print(res)package main
import(
"context"
"github.com/novuhq/novu-go/v3"
"github.com/novuhq/novu-go/v3/models/components"
"log"
)
func main() {
ctx := context.Background()
s := v3.New(
v3.WithSecurity("YOUR_SECRET_KEY_HERE"),
)
res, err := s.Topics.Subscriptions.Update(ctx, "<value>", "<value>", components.UpdateTopicSubscriptionRequestDto{
Name: v3.Pointer("My Subscription"),
Preferences: []components.UpdateTopicSubscriptionRequestDtoPreferences{
components.CreateUpdateTopicSubscriptionRequestDtoPreferencesWorkflowPreferenceRequestDto(
components.WorkflowPreferenceRequestDto{
Condition: map[string]any{
"===": []any{
map[string]any{
"var": "tier",
},
"premium",
},
},
WorkflowID: "workflow-123",
},
),
},
}, nil)
if err != nil {
log.Fatal(err)
}
if res.SubscriptionResponseDto != nil {
// handle response
}
}curl --request PATCH \
--url https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier} \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "My Subscription",
"preferences": [
{
"workflowId": "workflow-123",
"condition": {
"===": [
{
"var": "tier"
},
"premium"
]
}
}
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'My Subscription',
preferences: [{workflowId: 'workflow-123', condition: {'===': [{var: 'tier'}, 'premium']}}]
})
};
fetch('https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));HttpResponse<String> response = Unirest.patch("https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"My Subscription\",\n \"preferences\": [\n {\n \"workflowId\": \"workflow-123\",\n \"condition\": {\n \"===\": [\n {\n \"var\": \"tier\"\n },\n \"premium\"\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.novu.co/v2/topics/{topicKey}/subscriptions/{identifier}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"My Subscription\",\n \"preferences\": [\n {\n \"workflowId\": \"workflow-123\",\n \"condition\": {\n \"===\": [\n {\n \"var\": \"tier\"\n },\n \"premium\"\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"_id": "64f5e95d3d7946d80d0cb679",
"topic": {
"_id": "64f5e95d3d7946d80d0cb677",
"key": "product-updates",
"name": "Product Updates"
},
"subscriber": {
"_id": "64da692e9a94fb2e6449ad07",
"subscriberId": "user-123",
"avatar": "https://example.com/avatar.png",
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]"
},
"createdAt": "2025-04-24T05:40:21Z",
"updatedAt": "2025-04-24T05:40:21Z",
"identifier": "tk=product-updates:si=subscriber-123",
"name": "My Subscription",
"preferences": [
{
"subscriptionId": "64f5e95d3d7946d80d0cb679",
"enabled": true,
"workflow": {
"id": "64a1b2c3d4e5f6g7h8i9j0k1",
"identifier": "welcome-email",
"name": "Welcome Email Workflow",
"critical": false,
"tags": [
"user-onboarding",
"email"
],
"data": {
"category": "onboarding",
"priority": "high"
}
},
"condition": {
"and": [
{
"===": [
{
"var": "tier"
},
"premium"
]
}
]
}
}
],
"contextKeys": [
"tenant:org-a",
"project:proj-123"
]
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"errors": {
"fieldName1": {
"messages": [
"Field is required",
"Must be a valid email address"
],
"value": "invalidEmail"
},
"fieldName2": {
"messages": [
"Must be at least 18 years old"
],
"value": 17
},
"fieldName3": {
"messages": [
"Must be a boolean value"
],
"value": true
},
"fieldName4": {
"messages": [
"Must be a valid object"
],
"value": {
"key": "value"
}
},
"fieldName5": {
"messages": [
"Field is missing"
],
"value": null
},
"fieldName6": {
"messages": [
"Undefined value"
]
}
},
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"API rate limit exceeded"{
"statusCode": 404,
"timestamp": "2024-12-12T13:00:00Z",
"path": "/api/v1/resource",
"message": "xx xx xx ",
"ctx": {
"workflowId": "some_wf_id",
"stepId": "some_wf_id"
},
"errorId": "abc123"
}"Please wait some time, then try again."