diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 83a317a..7da4564 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -26,7 +26,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
- node-version: '20'
+ node-version: '24'
- name: Bootstrap
run: ./scripts/bootstrap
@@ -48,7 +48,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
- node-version: '20'
+ node-version: '24'
- name: Bootstrap
run: ./scripts/bootstrap
@@ -85,7 +85,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
- node-version: '20'
+ node-version: '24'
- name: Bootstrap
run: ./scripts/bootstrap
diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index 6384da5..54abaf2 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -22,7 +22,7 @@ jobs:
- name: Set up Node
uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
with:
- node-version: '20'
+ node-version: '24'
- name: Install dependencies
run: |
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f7e3c74..7f814da 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "7.19.2"
+ ".": "7.20.0"
}
diff --git a/.stats.yml b/.stats.yml
index 9e3b99b..809d9f7 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 138
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-11e1931d767cef402bbed5a965746d1933ae72db0f41881860593a0b1424fd80.yml
-openapi_spec_hash: 9def941805f233f8761c4bdae88f6137
-config_hash: 6c3a754258f0f77e9032a90a478ab76d
+configured_endpoints: 139
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-def1e982add0411bf64b48cdf5e4f2c1b85b9bd0ada0d5e6fc4869afa85e0bff.yml
+openapi_spec_hash: 5d129cdf800798bcd4a93585ec89c696
+config_hash: dcd58abf1e56b114bdce22336ca3d570
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96c5d95..10e420c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## 7.20.0 (2026-07-14)
+
+Full Changelog: [v7.19.2...v7.20.0](https://github.com/trycourier/courier-node/compare/v7.19.2...v7.20.0)
+
+### Features
+
+* Document POST /notifications/{id}/duplicate [C-18607] ([#165](https://github.com/trycourier/courier-node/issues/165)) ([95d4344](https://github.com/trycourier/courier-node/commit/95d43441e10fa2537b4be6667dd1e0534c811182))
+* Merge pull request [#149](https://github.com/trycourier/courier-node/issues/149) from trycourier/geraldosilva/c-19201-notification-template-subscription-topic-id ([7eae439](https://github.com/trycourier/courier-node/commit/7eae439cbfe287a079795e3e1954434ebf2baf82))
+
+
+### Bug Fixes
+
+* **ci:** bump @arethetypeswrong/cli to ^0.18.0 and run CI workflows on Node 24 ([d86d583](https://github.com/trycourier/courier-node/commit/d86d58376e67607a789c4961dba9cd011b093dfa))
+
## 7.19.2 (2026-07-10)
Full Changelog: [v7.19.1...v7.19.2](https://github.com/trycourier/courier-node/compare/v7.19.1...v7.19.2)
diff --git a/api.md b/api.md
index cf35e94..8ee88ea 100644
--- a/api.md
+++ b/api.md
@@ -401,6 +401,7 @@ Methods:
- client.notifications.retrieve(id, { ...params }) -> NotificationTemplateResponse
- client.notifications.list({ ...params }) -> NotificationListResponse
- client.notifications.archive(id) -> void
+- client.notifications.duplicate(id) -> NotificationTemplateResponse
- client.notifications.listVersions(id, { ...params }) -> NotificationTemplateVersionListResponse
- client.notifications.publish(id, { ...params }) -> void
- client.notifications.putContent(id, { ...params }) -> NotificationContentMutationResponse
diff --git a/package.json b/package.json
index 8b7d511..1b7fc84 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@trycourier/courier",
- "version": "7.19.2",
+ "version": "7.20.0",
"description": "The official TypeScript library for the Courier API",
"author": "Courier ",
"types": "dist/index.d.ts",
@@ -28,7 +28,7 @@
},
"dependencies": {},
"devDependencies": {
- "@arethetypeswrong/cli": "^0.17.0",
+ "@arethetypeswrong/cli": "^0.18.0",
"@swc/core": "^1.3.102",
"@swc/jest": "^0.2.29",
"@types/jest": "^29.4.0",
diff --git a/src/resources/notifications/notifications.ts b/src/resources/notifications/notifications.ts
index 47f8b29..6df2d99 100644
--- a/src/resources/notifications/notifications.ts
+++ b/src/resources/notifications/notifications.ts
@@ -98,6 +98,24 @@ export class Notifications extends APIResource {
});
}
+ /**
+ * Duplicate a notification template. Creates a standalone copy within the same
+ * workspace and environment, with " COPY" appended to the title. The copy clones
+ * the source draft's tags, brand, subscription topic, routing strategy, channels,
+ * and content, and is always created as a standalone template (it is not linked to
+ * any journey or broadcast, even if the source was). Templates that are scoped to
+ * a journey or a broadcast cannot be duplicated through this endpoint.
+ *
+ * @example
+ * ```ts
+ * const notificationTemplateResponse =
+ * await client.notifications.duplicate('id');
+ * ```
+ */
+ duplicate(id: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/notifications/${id}/duplicate`, options);
+ }
+
/**
* List versions of a notification template.
*
@@ -658,6 +676,12 @@ export interface NotificationTemplateSummary {
tags: Array;
+ /**
+ * The linked subscription (preference) topic of the published version. Omitted
+ * when no topic is linked or the template has never been published.
+ */
+ subscription_topic_id?: string;
+
/**
* Epoch milliseconds of last update.
*/
diff --git a/src/version.ts b/src/version.ts
index fdaf49d..7b73ac2 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '7.19.2'; // x-release-please-version
+export const VERSION = '7.20.0'; // x-release-please-version
diff --git a/tests/api-resources/notifications/notifications.test.ts b/tests/api-resources/notifications/notifications.test.ts
index 3fcd4d6..2dac876 100644
--- a/tests/api-resources/notifications/notifications.test.ts
+++ b/tests/api-resources/notifications/notifications.test.ts
@@ -103,6 +103,18 @@ describe('resource notifications', () => {
expect(dataAndResponse.response).toBe(rawResponse);
});
+ // Mock server tests are disabled
+ test.skip('duplicate', async () => {
+ const responsePromise = client.notifications.duplicate('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
// Mock server tests are disabled
test.skip('listVersions', async () => {
const responsePromise = client.notifications.listVersions('id');
diff --git a/yarn.lock b/yarn.lock
index 38236e6..443cc05 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12,12 +12,12 @@
resolved "https://registry.yarnpkg.com/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz#ba9494f85eb83017c5c855763969caf1d0adea00"
integrity sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==
-"@arethetypeswrong/cli@^0.17.0":
- version "0.17.0"
- resolved "https://registry.yarnpkg.com/@arethetypeswrong/cli/-/cli-0.17.0.tgz#f97f10926b3f9f9eb5117550242d2e06c25cadac"
- integrity sha512-xSMW7bfzVWpYw5JFgZqBXqr6PdR0/REmn3DkxCES5N0JTcB0CVgbIynJCvKBFmXaPc3hzmmTrb7+yPDRoOSZdA==
+"@arethetypeswrong/cli@^0.18.0":
+ version "0.18.4"
+ resolved "https://registry.yarnpkg.com/@arethetypeswrong/cli/-/cli-0.18.4.tgz#c31f54f3b0d0e0f3256ab3edb6530beeb5e64b4b"
+ integrity sha512-kNWo6LTzGAuLYPpJ7Sgo63whSUeeSuKMlYx6IBgzs4ONEG807gW4hSSENvpeCHzO2H2wIzG5EFl0OKBbqGBAyA==
dependencies:
- "@arethetypeswrong/core" "0.17.0"
+ "@arethetypeswrong/core" "0.18.4"
chalk "^4.1.2"
cli-table3 "^0.6.3"
commander "^10.0.1"
@@ -25,15 +25,16 @@
marked-terminal "^7.1.0"
semver "^7.5.4"
-"@arethetypeswrong/core@0.17.0":
- version "0.17.0"
- resolved "https://registry.yarnpkg.com/@arethetypeswrong/core/-/core-0.17.0.tgz#abb3b5f425056d37193644c2a2de4aecf866b76b"
- integrity sha512-FHyhFizXNetigTVsIhqXKGYLpazPS5YNojEPpZEUcBPt9wVvoEbNIvG+hybuBR+pjlRcbyuqhukHZm1fr+bDgA==
+"@arethetypeswrong/core@0.18.4":
+ version "0.18.4"
+ resolved "https://registry.yarnpkg.com/@arethetypeswrong/core/-/core-0.18.4.tgz#24edea3d651dea7d32bf6f1cc9ee9a00db39de49"
+ integrity sha512-M5F0ePyN6h2Z6XxRiyIPqjGbltotXLjR0CKA0uKspsDu0QmgTNYvRb4RSQPMUs2ZXZHCCYpbaZbFbYOXLxCjUA==
dependencies:
"@andrewbranch/untar.js" "^1.0.3"
+ "@loaderkit/resolve" "^1.0.2"
cjs-module-lexer "^1.2.3"
- fflate "^0.8.2"
- lru-cache "^10.4.3"
+ fflate "^0.8.3"
+ lru-cache "^11.0.1"
semver "^7.5.4"
typescript "5.6.1-rc"
validate-npm-package-name "^5.0.0"
@@ -306,6 +307,11 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@braidai/lang@^1.0.0":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@braidai/lang/-/lang-1.1.2.tgz#65bc2bc1db6d00e153b95ac7006f4573e289e9be"
+ integrity sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA==
+
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -688,6 +694,13 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
+"@loaderkit/resolve@^1.0.2":
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/@loaderkit/resolve/-/resolve-1.0.6.tgz#8d45341e688faecc25b3ae919c0f45d94c4e26c9"
+ integrity sha512-G8FdIoF5CypfwmD9rl8BXod5HDn8JqB0CCNBXDTaRZ+yRYhARrrSToX1zg1zy9jX3zLqigsELwhT4gNtkdQAUg==
+ dependencies:
+ "@braidai/lang" "^1.0.0"
+
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -1696,10 +1709,10 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
-fflate@^0.8.2:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea"
- integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==
+fflate@^0.8.3:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.3.tgz#bc27d8eb30343d4d512abb03480202ce65d825fc"
+ integrity sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==
file-entry-cache@^8.0.0:
version "8.0.0"
@@ -2490,10 +2503,10 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-lru-cache@^10.4.3:
- version "10.4.3"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
- integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
+lru-cache@^11.0.1:
+ version "11.5.2"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.2.tgz#00e16665c90c620fba14a3c368732a976493f760"
+ integrity sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==
lru-cache@^5.1.1:
version "5.1.1"