From 5f3c839c9aea887232c6ddc68db58654a01d7f1a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 23:15:11 +0000 Subject: [PATCH 1/3] docs(openapi): use canonical type-id prefixes in id examples (#160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(openapi): use canonical type-id prefixes in id examples Align example ids with the backend's type-id prefixes (backend staging, lib/courier-ids ID_PREFIXES): nt=notification, rs=routing-strategy, pc=provider-config, ps=preference-section, pt=preference-topic. - providers: prov_ -> pc_ (wrong prefix corrected) - preference sections: PS5QM... -> ps_ - preference topics: raw ULIDs and "marketing" -> distinct pt_ (the valid vs not-found example ids are kept distinct) - notifications / routing: normalize the fake-short nt_01abc123 / rs_01abc123 to valid 26-char typeids All new values are format-valid typeids (prefix_ + 26-char base32), generated with typeid-js. Scope is "typed fields only": path {id}/{section_id}/{topic_id} params and clearly-named id fields for the 5 entities that have prefixes. The shared generic placeholder abc-123 (used across many unrelated entities) and the already-correct, readable elem_* element ids are left as-is. Examples-only; no schema/contract change. Co-Authored-By: Claude Opus 4.8 * test(e2e): make the journeys invoke test self-contained The "lists journeys and invokes the first template" test invoked list.templates[0], which is flaky against the shared live workspace: when no journey happens to exist there the list is empty and the test fails on `expect(firstId).toBeDefined()` (data drift, not a regression). Every other test in this file creates its own journey; make this one do the same — create + publish a minimal api-invoke journey, then invoke it by id. `list` is still covered by the "lists journeys" test above. Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- .stats.yml | 4 ++-- src/resources/notifications/notifications.ts | 4 +++- src/resources/users/preferences.ts | 6 +++--- .../notifications/notifications.test.ts | 4 ++-- tests/api-resources/users/preferences.test.ts | 12 ++++++------ 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.stats.yml b/.stats.yml index c6ea0b34..70c7b0e0 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-e8d4bd51bf260b8a6cb9875718e36eab95d4e8d9490cd6c5c669eb69b82c2bf8.yml -openapi_spec_hash: bf321581a238ae891debcc5bb59dd501 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-6f6deee1badbf852c3040ab900f25716890cf5d0e71c59f1a6b770a7fb877500.yml +openapi_spec_hash: b22e111bf1a9a968c6c1ee427015a901 config_hash: 6c3a754258f0f77e9032a90a478ab76d diff --git a/src/resources/notifications/notifications.ts b/src/resources/notifications/notifications.ts index 94c877d9..1c0511ba 100644 --- a/src/resources/notifications/notifications.ts +++ b/src/resources/notifications/notifications.ts @@ -31,7 +31,9 @@ export class Notifications extends APIResource { * name: 'Welcome Email', * tags: ['onboarding', 'welcome'], * brand: { id: 'brand_abc' }, - * subscription: { topic_id: 'marketing' }, + * subscription: { + * topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t', + * }, * routing: { strategy_id: 'rs_123' }, * content: { * version: '2022-01-01', diff --git a/src/resources/users/preferences.ts b/src/resources/users/preferences.ts index 03129f90..decc3128 100644 --- a/src/resources/users/preferences.ts +++ b/src/resources/users/preferences.ts @@ -52,7 +52,7 @@ export class Preferences extends APIResource { * { * topics: [ * { - * topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT', + * topic_id: 'pt_01kx4h2jdafq8bk996nn92357r', * status: 'OPTED_IN', * has_custom_routing: true, * custom_routing: ['inbox', 'email'], @@ -97,13 +97,13 @@ export class Preferences extends APIResource { * { * topics: [ * { - * topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT', + * topic_id: 'pt_01kx4h2jdafq8bk996nn92357r', * status: 'OPTED_IN', * has_custom_routing: true, * custom_routing: ['inbox', 'email'], * }, * { - * topic_id: '5Q4QGFBEX481DP6JRPMV751H4YU', + * topic_id: 'pt_01kx4h2jdafq8bk99eyt3dx43x', * status: 'OPTED_OUT', * }, * ], diff --git a/tests/api-resources/notifications/notifications.test.ts b/tests/api-resources/notifications/notifications.test.ts index b5fcdfe3..bf03b652 100644 --- a/tests/api-resources/notifications/notifications.test.ts +++ b/tests/api-resources/notifications/notifications.test.ts @@ -16,7 +16,7 @@ describe('resource notifications', () => { content: { elements: [{}], version: '2022-01-01' }, name: 'Welcome Email', routing: { strategy_id: 'rs_123' }, - subscription: { topic_id: 'marketing' }, + subscription: { topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t' }, tags: ['onboarding', 'welcome'], }, }); @@ -37,7 +37,7 @@ describe('resource notifications', () => { content: { elements: [{ type: 'channel' }], version: '2022-01-01' }, name: 'Welcome Email', routing: { strategy_id: 'rs_123' }, - subscription: { topic_id: 'marketing' }, + subscription: { topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t' }, tags: ['onboarding', 'welcome'], }, state: 'DRAFT', diff --git a/tests/api-resources/users/preferences.test.ts b/tests/api-resources/users/preferences.test.ts index e0c418b7..ac55d15c 100644 --- a/tests/api-resources/users/preferences.test.ts +++ b/tests/api-resources/users/preferences.test.ts @@ -35,7 +35,7 @@ describe('resource preferences', () => { // Mock server tests are disabled test.skip('bulkReplace: only required params', async () => { const responsePromise = client.users.preferences.bulkReplace('user_id', { - topics: [{ status: 'OPTED_IN', topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT' }], + topics: [{ status: 'OPTED_IN', topic_id: 'pt_01kx4h2jdafq8bk996nn92357r' }], }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -52,7 +52,7 @@ describe('resource preferences', () => { topics: [ { status: 'OPTED_IN', - topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT', + topic_id: 'pt_01kx4h2jdafq8bk996nn92357r', custom_routing: ['inbox', 'email'], has_custom_routing: true, }, @@ -65,8 +65,8 @@ describe('resource preferences', () => { test.skip('bulkUpdate: only required params', async () => { const responsePromise = client.users.preferences.bulkUpdate('user_id', { topics: [ - { status: 'OPTED_IN', topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT' }, - { status: 'OPTED_OUT', topic_id: '5Q4QGFBEX481DP6JRPMV751H4YU' }, + { status: 'OPTED_IN', topic_id: 'pt_01kx4h2jdafq8bk996nn92357r' }, + { status: 'OPTED_OUT', topic_id: 'pt_01kx4h2jdafq8bk99eyt3dx43x' }, ], }); const rawResponse = await responsePromise.asResponse(); @@ -84,13 +84,13 @@ describe('resource preferences', () => { topics: [ { status: 'OPTED_IN', - topic_id: '74Q4QGFBEX481DP6JRPMV751H4XT', + topic_id: 'pt_01kx4h2jdafq8bk996nn92357r', custom_routing: ['inbox', 'email'], has_custom_routing: true, }, { status: 'OPTED_OUT', - topic_id: '5Q4QGFBEX481DP6JRPMV751H4YU', + topic_id: 'pt_01kx4h2jdafq8bk99eyt3dx43x', custom_routing: ['direct_message'], has_custom_routing: true, }, From 8e493e2b8dc6d2d0eeccc3ca658dd5503c0028e1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:04:34 +0000 Subject: [PATCH 2/3] docs(openapi): canonical type-id prefixes across all examples (#162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs(openapi): canonical type-id prefixes in remaining id examples Follow-up to #160, which normalized nt/rs/pc/ps/pt id examples but left a few prefixed-entity ids using placeholder/short values. Align these with the backend's canonical type-id prefixes (staging lib/courier-ids ID_PREFIXES): - routing: strategy_id "rs_123" -> valid rs_ typeid (matches the rs_ example used elsewhere in the spec) - error messages: "Notification template nt_nonexistent not found" and "Routing strategy rs_nonexistent not found" -> valid-format not-found typeids (distinct from the "exists" example ids, per #160's valid-vs-not-found convention) - error message: "Version not found for template nt_123" -> canonical nt_ typeid (the template exists; only the version is missing) All values are format-valid typeids (prefix_ + 26-char base32), generated with typeid-js. Readable elem_* element ids are left as-is (element ids are idiomatically human-readable in this spec). Examples-only; no schema/contract change. Co-Authored-By: Claude Opus 4.8 * docs(openapi): use canonical jry_ / nt_ ids in journey examples Latest backend staging lib/courier-ids ID_PREFIXES added a JOURNEY: "jry" prefix (journey create always generates a jry_ typeid). The journeys example ids were still placeholders — align them: - journey ids (list items, create/get/replace/publish responses): abc-123 / abc-123-def-456 / xyz-789-ghi-012 -> jry_ typeids - journey-scoped notification templates (POST /journeys/{templateId}/templates results): tmpl-1 / tmpl-2 -> nt_ typeids Left as-is: journey node ids (trigger-1, send-1) are user-authored readable ids; run_id/runId are X-Ray-style run identifiers, not typeids; brand/tenant ids stay readable placeholders (both accept customer-supplied ids, matching #160). /automations examples are untouched (automation template ids are composite tenant/env-scoped, not a bare jry_). All new values are format-valid typeids (prefix_ + 26-char base32), generated with typeid-js. Examples-only; no schema/contract change. Co-Authored-By: Claude Opus 4.8 * docs: canonical brand/notification/routing ids + release-shepherd note Complete the type-id sweep so every prefixed-entity example uses a canonical typeid, and document the release-shepherd skill. openapi.yml (examples-only, no schema/contract change): - brand ids -> bnd_ (Brand, BrandsResponse, Tenant/TenantListResponse brand_id, RoutingStrategyGetResponse brand_id, and brand.id in notification responses): brand now has a canonical bnd prefix on staging, so the placeholder ULID / brand_abc values are replaced - NotificationListResponse item id: abc-123 -> nt_ (was missed) - RoutingStrategyGetResponse id: abc-123 -> rs_ (was missed) - BulkGetJobUsersResponse templateId -> nt_ Left readable/untouched (not backend-generated typeids): tenant/workspace ids (customer-supplied, wrk_ is only the generated fallback), tag ids, submission-check ids, audit-event ids, and /automations template ids (composite tenant/env-scoped, not a bare jry_). README: add a note pointing to the courier-release-shepherd skill for driving the docs sync + SDK release PRs after a merge. Co-Authored-By: Claude Opus 4.8 --------- Co-authored-by: Claude Opus 4.8 --- .stats.yml | 4 ++-- src/resources/notifications/notifications.ts | 6 ++++-- tests/api-resources/notifications/notifications.test.ts | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 70c7b0e0..9e3b99b6 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-6f6deee1badbf852c3040ab900f25716890cf5d0e71c59f1a6b770a7fb877500.yml -openapi_spec_hash: b22e111bf1a9a968c6c1ee427015a901 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-11e1931d767cef402bbed5a965746d1933ae72db0f41881860593a0b1424fd80.yml +openapi_spec_hash: 9def941805f233f8761c4bdae88f6137 config_hash: 6c3a754258f0f77e9032a90a478ab76d diff --git a/src/resources/notifications/notifications.ts b/src/resources/notifications/notifications.ts index 1c0511ba..47f8b298 100644 --- a/src/resources/notifications/notifications.ts +++ b/src/resources/notifications/notifications.ts @@ -30,11 +30,13 @@ export class Notifications extends APIResource { * notification: { * name: 'Welcome Email', * tags: ['onboarding', 'welcome'], - * brand: { id: 'brand_abc' }, + * brand: { id: 'bnd_01kx4mrd0pfzw8wt7pn7p2fzag' }, * subscription: { * topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t', * }, - * routing: { strategy_id: 'rs_123' }, + * routing: { + * strategy_id: 'rs_01kx4h2jdafq8bk9amzvy6hbv0', + * }, * content: { * version: '2022-01-01', * elements: [{ type: 'channel' }], diff --git a/tests/api-resources/notifications/notifications.test.ts b/tests/api-resources/notifications/notifications.test.ts index bf03b652..3fcd4d6c 100644 --- a/tests/api-resources/notifications/notifications.test.ts +++ b/tests/api-resources/notifications/notifications.test.ts @@ -12,10 +12,10 @@ describe('resource notifications', () => { test.skip('create: only required params', async () => { const responsePromise = client.notifications.create({ notification: { - brand: { id: 'brand_abc' }, + brand: { id: 'bnd_01kx4mrd0pfzw8wt7pn7p2fzag' }, content: { elements: [{}], version: '2022-01-01' }, name: 'Welcome Email', - routing: { strategy_id: 'rs_123' }, + routing: { strategy_id: 'rs_01kx4h2jdafq8bk9amzvy6hbv0' }, subscription: { topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t' }, tags: ['onboarding', 'welcome'], }, @@ -33,10 +33,10 @@ describe('resource notifications', () => { test.skip('create: required and optional params', async () => { const response = await client.notifications.create({ notification: { - brand: { id: 'brand_abc' }, + brand: { id: 'bnd_01kx4mrd0pfzw8wt7pn7p2fzag' }, content: { elements: [{ type: 'channel' }], version: '2022-01-01' }, name: 'Welcome Email', - routing: { strategy_id: 'rs_123' }, + routing: { strategy_id: 'rs_01kx4h2jdafq8bk9amzvy6hbv0' }, subscription: { topic_id: 'pt_01kx4h2jdafq8bk9a26x0kvd1t' }, tags: ['onboarding', 'welcome'], }, From a941d847c52ba369394d71090e12640126b448ca Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:04:54 +0000 Subject: [PATCH 3/3] release: 7.19.2 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0b5216f2..f7e3c743 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "7.19.1" + ".": "7.19.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index c22c76f4..96c5d95d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 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) + +### Documentation + +* **openapi:** canonical type-id prefixes across all examples ([#162](https://github.com/trycourier/courier-node/issues/162)) ([8e493e2](https://github.com/trycourier/courier-node/commit/8e493e2b8dc6d2d0eeccc3ca658dd5503c0028e1)) +* **openapi:** use canonical type-id prefixes in id examples ([#160](https://github.com/trycourier/courier-node/issues/160)) ([5f3c839](https://github.com/trycourier/courier-node/commit/5f3c839c9aea887232c6ddc68db58654a01d7f1a)) + ## 7.19.1 (2026-07-09) Full Changelog: [v7.19.0...v7.19.1](https://github.com/trycourier/courier-node/compare/v7.19.0...v7.19.1) diff --git a/package.json b/package.json index eff922ad..8b7d5111 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@trycourier/courier", - "version": "7.19.1", + "version": "7.19.2", "description": "The official TypeScript library for the Courier API", "author": "Courier ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index fd2eb290..fdaf49de 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '7.19.1'; // x-release-please-version +export const VERSION = '7.19.2'; // x-release-please-version