From e4008818317bdee7b7c2f65b64d3f155bf3458a8 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:09 +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 ++-- tests/Services/NotificationsTest.php | 4 ++-- tests/Services/Users/PreferencesTest.php | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.stats.yml b/.stats.yml index c6ea0b3..70c7b0e 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/tests/Services/NotificationsTest.php b/tests/Services/NotificationsTest.php index a6a0438..2810dfb 100644 --- a/tests/Services/NotificationsTest.php +++ b/tests/Services/NotificationsTest.php @@ -45,7 +45,7 @@ public function testCreate(): void 'content' => ['elements' => [[]], 'version' => '2022-01-01'], 'name' => 'Welcome Email', 'routing' => ['strategyID' => 'rs_123'], - 'subscription' => ['topicID' => 'marketing'], + 'subscription' => ['topicID' => 'pt_01kx4h2jdafq8bk9a26x0kvd1t'], 'tags' => ['onboarding', 'welcome'], ], ); @@ -69,7 +69,7 @@ public function testCreateWithOptionalParams(): void ], 'name' => 'Welcome Email', 'routing' => ['strategyID' => 'rs_123'], - 'subscription' => ['topicID' => 'marketing'], + 'subscription' => ['topicID' => 'pt_01kx4h2jdafq8bk9a26x0kvd1t'], 'tags' => ['onboarding', 'welcome'], ], state: 'DRAFT', diff --git a/tests/Services/Users/PreferencesTest.php b/tests/Services/Users/PreferencesTest.php index a22c494..60cc9e1 100644 --- a/tests/Services/Users/PreferencesTest.php +++ b/tests/Services/Users/PreferencesTest.php @@ -57,7 +57,7 @@ public function testBulkReplace(): void $result = $this->client->users->preferences->bulkReplace( 'user_id', topics: [ - ['status' => 'OPTED_IN', 'topicID' => '74Q4QGFBEX481DP6JRPMV751H4XT'], + ['status' => 'OPTED_IN', 'topicID' => 'pt_01kx4h2jdafq8bk996nn92357r'], ], ); @@ -77,7 +77,7 @@ public function testBulkReplaceWithOptionalParams(): void topics: [ [ 'status' => 'OPTED_IN', - 'topicID' => '74Q4QGFBEX481DP6JRPMV751H4XT', + 'topicID' => 'pt_01kx4h2jdafq8bk996nn92357r', 'customRouting' => [ ChannelClassification::INBOX, ChannelClassification::EMAIL, ], @@ -101,8 +101,8 @@ public function testBulkUpdate(): void $result = $this->client->users->preferences->bulkUpdate( 'user_id', topics: [ - ['status' => 'OPTED_IN', 'topicID' => '74Q4QGFBEX481DP6JRPMV751H4XT'], - ['status' => 'OPTED_OUT', 'topicID' => '5Q4QGFBEX481DP6JRPMV751H4YU'], + ['status' => 'OPTED_IN', 'topicID' => 'pt_01kx4h2jdafq8bk996nn92357r'], + ['status' => 'OPTED_OUT', 'topicID' => 'pt_01kx4h2jdafq8bk99eyt3dx43x'], ], ); @@ -122,7 +122,7 @@ public function testBulkUpdateWithOptionalParams(): void topics: [ [ 'status' => 'OPTED_IN', - 'topicID' => '74Q4QGFBEX481DP6JRPMV751H4XT', + 'topicID' => 'pt_01kx4h2jdafq8bk996nn92357r', 'customRouting' => [ ChannelClassification::INBOX, ChannelClassification::EMAIL, ], @@ -130,7 +130,7 @@ public function testBulkUpdateWithOptionalParams(): void ], [ 'status' => 'OPTED_OUT', - 'topicID' => '5Q4QGFBEX481DP6JRPMV751H4YU', + 'topicID' => 'pt_01kx4h2jdafq8bk99eyt3dx43x', 'customRouting' => [ChannelClassification::DIRECT_MESSAGE], 'hasCustomRouting' => true, ], From 1f883cb20d6675abf337f0eb18b84d90472e5f4b 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:29 +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 ++-- tests/Services/NotificationsTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.stats.yml b/.stats.yml index 70c7b0e..9e3b99b 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/tests/Services/NotificationsTest.php b/tests/Services/NotificationsTest.php index 2810dfb..5e9ce3c 100644 --- a/tests/Services/NotificationsTest.php +++ b/tests/Services/NotificationsTest.php @@ -41,10 +41,10 @@ public function testCreate(): void $result = $this->client->notifications->create( notification: [ - 'brand' => ['id' => 'brand_abc'], + 'brand' => ['id' => 'bnd_01kx4mrd0pfzw8wt7pn7p2fzag'], 'content' => ['elements' => [[]], 'version' => '2022-01-01'], 'name' => 'Welcome Email', - 'routing' => ['strategyID' => 'rs_123'], + 'routing' => ['strategyID' => 'rs_01kx4h2jdafq8bk9amzvy6hbv0'], 'subscription' => ['topicID' => 'pt_01kx4h2jdafq8bk9a26x0kvd1t'], 'tags' => ['onboarding', 'welcome'], ], @@ -63,12 +63,12 @@ public function testCreateWithOptionalParams(): void $result = $this->client->notifications->create( notification: [ - 'brand' => ['id' => 'brand_abc'], + 'brand' => ['id' => 'bnd_01kx4mrd0pfzw8wt7pn7p2fzag'], 'content' => [ 'elements' => [['type' => 'channel']], 'version' => '2022-01-01', ], 'name' => 'Welcome Email', - 'routing' => ['strategyID' => 'rs_123'], + 'routing' => ['strategyID' => 'rs_01kx4h2jdafq8bk9amzvy6hbv0'], 'subscription' => ['topicID' => 'pt_01kx4h2jdafq8bk9a26x0kvd1t'], 'tags' => ['onboarding', 'welcome'], ], From 2088c7b38761ff952d1a15bce70d7924865c9278 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: 5.11.2 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ src/Version.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f5c6dea..1363fe0 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "5.11.1" + ".": "5.11.2" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 549166f..c9bf108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 5.11.2 (2026-07-10) + +Full Changelog: [v5.11.1...v5.11.2](https://github.com/trycourier/courier-php/compare/v5.11.1...v5.11.2) + +### Documentation + +* **openapi:** canonical type-id prefixes across all examples ([#162](https://github.com/trycourier/courier-php/issues/162)) ([1f883cb](https://github.com/trycourier/courier-php/commit/1f883cb20d6675abf337f0eb18b84d90472e5f4b)) +* **openapi:** use canonical type-id prefixes in id examples ([#160](https://github.com/trycourier/courier-php/issues/160)) ([e400881](https://github.com/trycourier/courier-php/commit/e4008818317bdee7b7c2f65b64d3f155bf3458a8)) + ## 5.11.1 (2026-07-09) Full Changelog: [v5.11.0...v5.11.1](https://github.com/trycourier/courier-php/compare/v5.11.0...v5.11.1) diff --git a/src/Version.php b/src/Version.php index 366453a..256e768 100644 --- a/src/Version.php +++ b/src/Version.php @@ -5,5 +5,5 @@ namespace Courier; // x-release-please-start-version -const VERSION = '5.11.1'; +const VERSION = '5.11.2'; // x-release-please-end