From 842699a68811d63aca9ef8d8865266623ff3e42c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 23 Jul 2026 23:47:02 +0000 Subject: [PATCH 1/3] docs(openapi): describe user topic-preference fields explicitly (#172) Add field descriptions to UsersTopicPreference and UsersTopicPreferenceUpdate so the generated API reference documents them fully (topic_id, status, default_status, has_custom_routing, custom_routing, topic_name), including the REQUIRED-is-a-topic-default semantics and the custom_routing channel set. Wrap the PreferenceStatus $ref fields in allOf so the description renders under OpenAPI 3.0. Co-authored-by: Claude Opus 4.8 (1M context) --- .stats.yml | 4 ++-- ...reference_update_or_create_topic_params.py | 14 +++++++++++- src/courier/types/users/topic_preference.py | 22 ++++++++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index e2794c72..e5f81212 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 134 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-b053468fefe6d757f86f3233ebbc52d80329ed2a6e7a6740fee01e4028a4c3b9.yml -openapi_spec_hash: 416835e693de0fe19945be90a787d3f3 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-0630b37ff5ba795185e1e189b0f24d233ecd51681b6ebb7748cad8f0e8c4fcc0.yml +openapi_spec_hash: b9a8c66633e914c9a2f7b3bf275c7349 config_hash: 8d28dbeabe9d4dcc7d5b8c021a4cbbd7 diff --git a/src/courier/types/users/preference_update_or_create_topic_params.py b/src/courier/types/users/preference_update_or_create_topic_params.py index 434de14b..6eb74fdd 100644 --- a/src/courier/types/users/preference_update_or_create_topic_params.py +++ b/src/courier/types/users/preference_update_or_create_topic_params.py @@ -22,8 +22,20 @@ class PreferenceUpdateOrCreateTopicParams(TypedDict, total=False): class Topic(TypedDict, total=False): status: Required[PreferenceStatus] + """The subscription status to set: OPTED_IN or OPTED_OUT. + + REQUIRED is a topic-level default, not a user choice; the API rejects opting a + user out of a REQUIRED topic. + """ custom_routing: Optional[List[ChannelClassification]] - """The Channels a user has chosen to receive notifications through for this topic""" + """The channels to deliver this topic on when has_custom_routing is true. + + One or more of: direct_message, email, push, sms, webhook, inbox. + """ has_custom_routing: Optional[bool] + """ + Set to true to route this topic to the channels in custom_routing instead of the + topic's default routing. + """ diff --git a/src/courier/types/users/topic_preference.py b/src/courier/types/users/topic_preference.py index 55e74c03..b719e0e8 100644 --- a/src/courier/types/users/topic_preference.py +++ b/src/courier/types/users/topic_preference.py @@ -11,14 +11,34 @@ class TopicPreference(BaseModel): default_status: PreferenceStatus + """The topic's default status, returned on reads. + + It applies whenever the user has no override of their own (status equals this + value). + """ status: PreferenceStatus + """The user's subscription status for this topic. + + OPTED_IN or OPTED_OUT reflect the user's own choice; REQUIRED is a topic-level + default set in the preferences editor, not a user choice. + """ topic_id: str + """The unique identifier of the subscription topic this preference applies to.""" topic_name: str + """The display name of the subscription topic, returned on reads.""" custom_routing: Optional[List[ChannelClassification]] = None - """The Channels a user has chosen to receive notifications through for this topic""" + """ + The channels the user has chosen to receive this topic on, present only when + has_custom_routing is true. One or more of: direct_message, email, push, sms, + webhook, inbox. + """ has_custom_routing: Optional[bool] = None + """ + Whether the user has chosen specific delivery channels for this topic (listed in + custom_routing) rather than the topic's default routing. + """ From c90b5d325da4e542a46a089084205ce145d65ef1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 00:05:33 +0000 Subject: [PATCH 2/3] docs(openapi): rewrite operation descriptions for agents and SEO (#174) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrites the `description` on 116 of 134 operations and fills in 14 that had none (GET /tenants, PUT /tenants/{id}, and other tenant/token/message operations). The 18 already-good descriptions are untouched. Why: these descriptions feed the API reference, the generated llms.txt, and the SDK docstrings across all seven languages. Many were either too terse to be useful to a coding agent (e.g. "Returns the specified audience by id") or long enough that Mintlify truncated them mid-sentence in llms.txt (10 sat at 300-301 chars). A prior SEO pass in mintlify-docs (#563) was silently reverted by spec syncs because it edited the generated mirror instead of this source file — this lands the work where it survives. House style, applied uniformly: - Sentence one states what the operation does using concrete nouns — actual response fields, enum values, and id formats, not vague paraphrase. - Sentence two, when present, gives the reason to reach for it or the behavior that surprises people. No status codes, validation rules, em-dashes, or marketing adjectives (those live in the reference body). - 95-160 characters, so they read fully in Google results and don't truncate in llms.txt. Each description was written against the operation's schema (required params, response properties, enums), not from assumption. This caught real errors: the message status enum has 12 values and does not include UNDELIVERABLE; POST /auth/issue-token requires both scope and expires_in (it is not "short-lived"); message content lives at /messages/{id}/output. Please give a domain check to three where behavior was inferred from HTTP semantics rather than stated in the schema: - PUT /users/{user_id}/tenants (users_tenants_addMultiple) — worded to only claim it adds; does it also remove tenants not listed in the body? - PUT /notifications/{id}/{submissionId}/checks (replaceSubmissionChecks) — worded as "the complete set supplied"; are omitted checks dropped? - GET /translations/{domain}/{locale} — says "notification content"; confirm the term. Mechanical: only operation-level `description` lines changed (verified: 0 operationId lines touched, 0 non-description lines added). Multi-line block scalars were collapsed to single quoted lines, which accounts for the deletion count. openapi.yml still parses and all 134 operations are intact. Co-authored-by: Claude --- .stats.yml | 4 +- src/courier/resources/audiences.py | 42 +++-- src/courier/resources/audit_events.py | 18 ++- src/courier/resources/auth.py | 12 +- .../resources/automations/automations.py | 16 +- src/courier/resources/automations/invoke.py | 24 ++- src/courier/resources/brands.py | 48 +++--- src/courier/resources/digests/schedules.py | 16 +- src/courier/resources/inbound.py | 18 ++- src/courier/resources/journeys/journeys.py | 148 +++++++----------- src/courier/resources/journeys/templates.py | 84 +++++----- src/courier/resources/lists/lists.py | 48 ++++-- src/courier/resources/lists/subscriptions.py | 26 +-- src/courier/resources/messages.py | 64 ++++---- src/courier/resources/notifications/checks.py | 24 ++- .../resources/notifications/notifications.py | 124 +++++++-------- src/courier/resources/profiles/lists.py | 38 +++-- src/courier/resources/profiles/profiles.py | 52 +++--- src/courier/resources/providers/catalog.py | 12 +- src/courier/resources/providers/providers.py | 68 ++++---- src/courier/resources/requests.py | 12 +- src/courier/resources/routing_strategies.py | 26 ++- src/courier/resources/send.py | 12 +- .../resources/tenants/preferences/items.py | 12 +- .../resources/tenants/templates/templates.py | 60 +++---- .../resources/tenants/templates/versions.py | 18 +-- src/courier/resources/tenants/tenants.py | 42 +++-- src/courier/resources/translations.py | 18 ++- src/courier/resources/users/preferences.py | 112 ++++--------- src/courier/resources/users/tenants.py | 64 ++++---- src/courier/resources/users/tokens.py | 36 +++-- .../resources/workspace_preferences/topics.py | 50 +++--- .../workspace_preferences.py | 50 +++--- 33 files changed, 670 insertions(+), 728 deletions(-) diff --git a/.stats.yml b/.stats.yml index e5f81212..48e48092 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 134 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-0630b37ff5ba795185e1e189b0f24d233ecd51681b6ebb7748cad8f0e8c4fcc0.yml -openapi_spec_hash: b9a8c66633e914c9a2f7b3bf275c7349 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/courier/courier-5c878919b3df530781ebcd4ab1cda83606304da75c53fe0817d4c725d5bbbe73.yml +openapi_spec_hash: dd37022222543ff064200e65e4b82f59 config_hash: 8d28dbeabe9d4dcc7d5b8c021a4cbbd7 diff --git a/src/courier/resources/audiences.py b/src/courier/resources/audiences.py index 4c930bdb..89bc7835 100644 --- a/src/courier/resources/audiences.py +++ b/src/courier/resources/audiences.py @@ -60,7 +60,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Audience: """ - Returns the specified audience by id. + Returns one audience with its name, description, and the filter and AND or OR + operator that decide which users belong to it. Args: extra_headers: Send extra headers @@ -97,7 +98,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceUpdateResponse: """ - Creates or updates audience. + Creates or replaces an audience from a filter and an AND or OR operator. + Membership recalculates automatically as profiles change. Args: description: A description of the audience @@ -148,8 +150,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceListResponse: - """ - Get the audiences associated with the authorization token. + """Returns the audiences in the workspace with paging. + + Audiences are filter-based + groups that recalculate as user profiles change. Args: cursor: A unique identifier that allows for fetching the next set of audiences @@ -186,7 +190,8 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Deletes the specified audience. + Deletes an audience permanently, so update any caller sending to it by audience + id first. Those sends fail once the audience is gone. Args: extra_headers: Send extra headers @@ -220,8 +225,10 @@ def list_members( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceListMembersResponse: - """ - Get list of members of an audience. + """Returns the users currently matching an audience filter, with paging. + + Membership + is recalculated, so results shift as profiles change. Args: cursor: A unique identifier that allows for fetching the next set of members @@ -281,7 +288,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Audience: """ - Returns the specified audience by id. + Returns one audience with its name, description, and the filter and AND or OR + operator that decide which users belong to it. Args: extra_headers: Send extra headers @@ -318,7 +326,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceUpdateResponse: """ - Creates or updates audience. + Creates or replaces an audience from a filter and an AND or OR operator. + Membership recalculates automatically as profiles change. Args: description: A description of the audience @@ -369,8 +378,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceListResponse: - """ - Get the audiences associated with the authorization token. + """Returns the audiences in the workspace with paging. + + Audiences are filter-based + groups that recalculate as user profiles change. Args: cursor: A unique identifier that allows for fetching the next set of audiences @@ -407,7 +418,8 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Deletes the specified audience. + Deletes an audience permanently, so update any caller sending to it by audience + id first. Those sends fail once the audience is gone. Args: extra_headers: Send extra headers @@ -441,8 +453,10 @@ async def list_members( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AudienceListMembersResponse: - """ - Get list of members of an audience. + """Returns the users currently matching an audience filter, with paging. + + Membership + is recalculated, so results shift as profiles change. Args: cursor: A unique identifier that allows for fetching the next set of members diff --git a/src/courier/resources/audit_events.py b/src/courier/resources/audit_events.py index 0323e1fc..289597ab 100644 --- a/src/courier/resources/audit_events.py +++ b/src/courier/resources/audit_events.py @@ -56,7 +56,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuditEvent: """ - Fetch a specific audit event by ID. + Returns one audit event by id, including the actor who performed it, the target + they changed, the source, the event type, and a timestamp. Args: extra_headers: Send extra headers @@ -88,8 +89,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuditEventListResponse: - """ - Fetch the list of audit events + """Returns the workspace's audit event log with cursor paging. + + Each event records + the actor, target, source, type, and timestamp of a change. Args: cursor: A unique identifier that allows for fetching the next set of audit events. @@ -147,7 +150,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuditEvent: """ - Fetch a specific audit event by ID. + Returns one audit event by id, including the actor who performed it, the target + they changed, the source, the event type, and a timestamp. Args: extra_headers: Send extra headers @@ -179,8 +183,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuditEventListResponse: - """ - Fetch the list of audit events + """Returns the workspace's audit event log with cursor paging. + + Each event records + the actor, target, source, type, and timestamp of a change. Args: cursor: A unique identifier that allows for fetching the next set of audit events. diff --git a/src/courier/resources/auth.py b/src/courier/resources/auth.py index b7b00ad1..4ba679c9 100644 --- a/src/courier/resources/auth.py +++ b/src/courier/resources/auth.py @@ -53,8 +53,10 @@ def issue_token( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuthIssueTokenResponse: - """ - Returns a new access token. + """Returns a JWT for authenticating client-side SDKs such as the Inbox. + + You supply + the scope and an expires_in duration, both required. Args: expires_in: @@ -143,8 +145,10 @@ async def issue_token( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AuthIssueTokenResponse: - """ - Returns a new access token. + """Returns a JWT for authenticating client-side SDKs such as the Inbox. + + You supply + the scope and an expires_in duration, both required. Args: expires_in: diff --git a/src/courier/resources/automations/automations.py b/src/courier/resources/automations/automations.py index fd29b8a3..00635564 100644 --- a/src/courier/resources/automations/automations.py +++ b/src/courier/resources/automations/automations.py @@ -67,12 +67,12 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationTemplateListResponse: - """Get the list of automations. + """ + Lists the workspace's saved automation templates, each with its id and a cursor + for paging to the next page of results. Args: - cursor: A cursor token for pagination. - - Use the cursor from the previous response to + cursor: A cursor token for pagination. Use the cursor from the previous response to fetch the next page of results. version: The version of templates to retrieve. Accepted values are published (for @@ -141,12 +141,12 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationTemplateListResponse: - """Get the list of automations. + """ + Lists the workspace's saved automation templates, each with its id and a cursor + for paging to the next page of results. Args: - cursor: A cursor token for pagination. - - Use the cursor from the previous response to + cursor: A cursor token for pagination. Use the cursor from the previous response to fetch the next page of results. version: The version of templates to retrieve. Accepted values are published (for diff --git a/src/courier/resources/automations/invoke.py b/src/courier/resources/automations/invoke.py index 7ec143ec..1ecaf91b 100644 --- a/src/courier/resources/automations/invoke.py +++ b/src/courier/resources/automations/invoke.py @@ -59,12 +59,9 @@ def invoke_ad_hoc( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationInvokeResponse: - """Invoke an ad hoc automation run. - - This endpoint accepts a JSON payload with a - series of automation steps. For information about what steps are available, - checkout the ad hoc automation guide - [here](https://www.courier.com/docs/automations/steps/). + """ + Runs a series of automation steps supplied inline, without a saved template, and + returns a runId. Args: extra_headers: Send extra headers @@ -111,7 +108,8 @@ def invoke_by_template( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationInvokeResponse: """ - Invoke an automation run from an automation template. + Starts an automation run from a saved template for one recipient, with optional + data and profile, and returns a runId. Args: extra_headers: Send extra headers @@ -179,12 +177,9 @@ async def invoke_ad_hoc( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationInvokeResponse: - """Invoke an ad hoc automation run. - - This endpoint accepts a JSON payload with a - series of automation steps. For information about what steps are available, - checkout the ad hoc automation guide - [here](https://www.courier.com/docs/automations/steps/). + """ + Runs a series of automation steps supplied inline, without a saved template, and + returns a runId. Args: extra_headers: Send extra headers @@ -231,7 +226,8 @@ async def invoke_by_template( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AutomationInvokeResponse: """ - Invoke an automation run from an automation template. + Starts an automation run from a saved template for one recipient, with optional + data and profile, and returns a runId. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/brands.py b/src/courier/resources/brands.py index 93754218..1f942d76 100644 --- a/src/courier/resources/brands.py +++ b/src/courier/resources/brands.py @@ -60,10 +60,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: - """Create a new brand. + """Creates a brand from a name and settings, including primary and secondary + colors. - Requires `name` and `settings` (with at least - `colors.primary` and `colors.secondary`). + Brands supply the logo, colors, and styling that templates render with. Args: extra_headers: Send extra headers @@ -103,7 +103,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: """ - Fetch a specific brand by brand ID. + Returns one brand by id, including its colors, logo and styling settings, + Handlebars snippets, and published version. Args: extra_headers: Send extra headers @@ -139,7 +140,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: """ - Replace an existing brand with the supplied values. + Replaces a brand with the values you supply, so send the complete settings and + snippets rather than only the fields you want changed. Args: name: The name of the brand. @@ -181,8 +183,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrandListResponse: - """ - Get the list of brands. + """Lists the workspace's brands. + + Every entry carries its name, styling settings, + snippets, and published version. Args: cursor: A unique identifier that allows for fetching the next set of brands. @@ -218,8 +222,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a brand by brand ID. + """Deletes a brand by id. + + Reassign any template or tenant that references it before + deleting to keep their styling intact. Args: extra_headers: Send extra headers @@ -276,10 +282,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: - """Create a new brand. + """Creates a brand from a name and settings, including primary and secondary + colors. - Requires `name` and `settings` (with at least - `colors.primary` and `colors.secondary`). + Brands supply the logo, colors, and styling that templates render with. Args: extra_headers: Send extra headers @@ -319,7 +325,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: """ - Fetch a specific brand by brand ID. + Returns one brand by id, including its colors, logo and styling settings, + Handlebars snippets, and published version. Args: extra_headers: Send extra headers @@ -355,7 +362,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Brand: """ - Replace an existing brand with the supplied values. + Replaces a brand with the values you supply, so send the complete settings and + snippets rather than only the fields you want changed. Args: name: The name of the brand. @@ -397,8 +405,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BrandListResponse: - """ - Get the list of brands. + """Lists the workspace's brands. + + Every entry carries its name, styling settings, + snippets, and published version. Args: cursor: A unique identifier that allows for fetching the next set of brands. @@ -434,8 +444,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a brand by brand ID. + """Deletes a brand by id. + + Reassign any template or tenant that references it before + deleting to keep their styling intact. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/digests/schedules.py b/src/courier/resources/digests/schedules.py index d92f7653..4c488392 100644 --- a/src/courier/resources/digests/schedules.py +++ b/src/courier/resources/digests/schedules.py @@ -54,11 +54,9 @@ def list_instances( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DigestInstanceListResponse: - """List the digest instances for a schedule. - - Each instance represents the events - accumulated for a single user against the schedule, and can be used to monitor - digest accumulation before the digest is released. + """ + Returns the digest instances for a schedule, one per user, with cursor paging. + Use it to see what has accumulated before a digest releases. Args: cursor: A cursor token from a previous response, used to fetch the next page of results. @@ -163,11 +161,9 @@ async def list_instances( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> DigestInstanceListResponse: - """List the digest instances for a schedule. - - Each instance represents the events - accumulated for a single user against the schedule, and can be used to monitor - digest accumulation before the digest is released. + """ + Returns the digest instances for a schedule, one per user, with cursor paging. + Use it to see what has accumulated before a digest releases. Args: cursor: A cursor token from a previous response, used to fetch the next page of results. diff --git a/src/courier/resources/inbound.py b/src/courier/resources/inbound.py index 4c1a58c9..9474c374 100644 --- a/src/courier/resources/inbound.py +++ b/src/courier/resources/inbound.py @@ -59,12 +59,13 @@ def track_event( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InboundTrackEventResponse: - """Courier Track Event + """Records an inbound event that can trigger a journey. - Args: - event: A descriptive name of the event. + Requires an event name, a + messageId you generate, a type, and a properties object. - This name will appear as a trigger in the + Args: + event: A descriptive name of the event. This name will appear as a trigger in the Courier Automation Trigger node. message_id: A required unique identifier that will be used to de-duplicate requests. If not @@ -134,12 +135,13 @@ async def track_event( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> InboundTrackEventResponse: - """Courier Track Event + """Records an inbound event that can trigger a journey. - Args: - event: A descriptive name of the event. + Requires an event name, a + messageId you generate, a type, and a properties object. - This name will appear as a trigger in the + Args: + event: A descriptive name of the event. This name will appear as a trigger in the Courier Automation Trigger node. message_id: A required unique identifier that will be used to de-duplicate requests. If not diff --git a/src/courier/resources/journeys/journeys.py b/src/courier/resources/journeys/journeys.py index c71614e6..d85cf354 100644 --- a/src/courier/resources/journeys/journeys.py +++ b/src/courier/resources/journeys/journeys.py @@ -85,14 +85,9 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Create a journey. - - Defaults to `DRAFT` state; pass `state: "PUBLISHED"` to - publish on create. Send nodes are not allowed on `POST`. The standard flow is: - create the journey shell here, add notification templates with - `POST /journeys/{templateId}/templates`, then wire them into the journey with - `PUT /journeys/{templateId}`. Call `POST /journeys/{templateId}/publish` to - publish a draft after the fact. + """ + Creates a journey from a set of nodes, in draft state unless you pass a + published state. Send nodes cannot be included until their templates exist. Args: state: Lifecycle state of a journey. @@ -176,12 +171,12 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneysListResponse: - """Get the list of journeys. + """ + Lists the workspace's journeys, each carrying a name, state, and enabled flag. + Paged by cursor. Args: - cursor: A cursor token for pagination. - - Use the cursor from the previous response to + cursor: A cursor token for pagination. Use the cursor from the previous response to fetch the next page of results. version: The version of journeys to retrieve. Accepted values are published (for @@ -224,10 +219,10 @@ def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive a journey. + """Archives a journey so it can no longer be invoked. - Archived journeys cannot be invoked. Existing journey runs - continue to completion. + Runs already in flight + continue to completion, so archiving never strands a user mid-sequence. Args: extra_headers: Send extra headers @@ -261,14 +256,9 @@ def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CancelJourneyResponse: - """Cancel journey runs. - - The request body must include EXACTLY ONE of - `cancelation_token` (cancels every run associated with the token) or `run_id` - (cancels a single tenant-scoped run). Supplying both or neither returns a `400`. - A `run_id` that does not match a run for the tenant returns `404`. Cancelation - is idempotent: a run that has already finished (`PROCESSED`/`ERROR`) or was - already `CANCELED` is left unchanged and its current status is returned. + """ + Cancels in-flight journey runs, either every run sharing a cancelation token or + one run by id. Use it to stop a sequence when the event resolves. Args: extra_headers: Send extra headers @@ -293,14 +283,9 @@ def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CancelJourneyResponse: - """Cancel journey runs. - - The request body must include EXACTLY ONE of - `cancelation_token` (cancels every run associated with the token) or `run_id` - (cancels a single tenant-scoped run). Supplying both or neither returns a `400`. - A `run_id` that does not match a run for the tenant returns `404`. Cancelation - is idempotent: a run that has already finished (`PROCESSED`/`ERROR`) or was - already `CANCELED` is left unchanged and its current status is returned. + """ + Cancels in-flight journey runs, either every run sharing a cancelation token or + one run by id. Use it to stop a sequence when the event resolves. Args: extra_headers: Send extra headers @@ -360,10 +345,10 @@ def invoke( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneysInvokeResponse: - """Invoke a journey by id or alias to start a new run. + """Starts a journey run for one user and returns a runId. - The response includes a - `runId` identifying the run. + Runs execute + asynchronously, so the response arrives before any message is sent. Args: data: Data payload passed to the journey. The expected shape can be predefined using @@ -419,7 +404,8 @@ def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyVersionsListResponse: """ - List published versions of a journey, ordered most recent first. + Lists a journey's published versions, most recent first, so you have a version + id to roll back to. Paged by cursor. Args: extra_headers: Send extra headers @@ -452,11 +438,9 @@ def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Publish the current draft as a new version. - - Body is optional; pass - `{ "version": "vN" }` to roll back to a prior version instead. Returns 404 if - the journey has no draft to publish. + """ + Publishes a journey's current draft as a new version, making it live for new + runs. Pass a version instead to roll back to an earlier one. Args: extra_headers: Send extra headers @@ -493,13 +477,9 @@ def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Replace the journey draft. - - Updates the working draft only; call - `POST /journeys/{templateId}/publish` to make it live, or pass - `state: "PUBLISHED"` in this request to publish immediately. Send-node - `template` ids must already exist and be scoped to this journey, and node ids - must not be claimed by another journey. + """ + Replaces a journey's working draft, leaving the published version live until you + publish. Reach for this when editing a journey already running. Args: state: Lifecycle state of a journey. @@ -570,14 +550,9 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Create a journey. - - Defaults to `DRAFT` state; pass `state: "PUBLISHED"` to - publish on create. Send nodes are not allowed on `POST`. The standard flow is: - create the journey shell here, add notification templates with - `POST /journeys/{templateId}/templates`, then wire them into the journey with - `PUT /journeys/{templateId}`. Call `POST /journeys/{templateId}/publish` to - publish a draft after the fact. + """ + Creates a journey from a set of nodes, in draft state unless you pass a + published state. Send nodes cannot be included until their templates exist. Args: state: Lifecycle state of a journey. @@ -661,12 +636,12 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneysListResponse: - """Get the list of journeys. + """ + Lists the workspace's journeys, each carrying a name, state, and enabled flag. + Paged by cursor. Args: - cursor: A cursor token for pagination. - - Use the cursor from the previous response to + cursor: A cursor token for pagination. Use the cursor from the previous response to fetch the next page of results. version: The version of journeys to retrieve. Accepted values are published (for @@ -709,10 +684,10 @@ async def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive a journey. + """Archives a journey so it can no longer be invoked. - Archived journeys cannot be invoked. Existing journey runs - continue to completion. + Runs already in flight + continue to completion, so archiving never strands a user mid-sequence. Args: extra_headers: Send extra headers @@ -746,14 +721,9 @@ async def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CancelJourneyResponse: - """Cancel journey runs. - - The request body must include EXACTLY ONE of - `cancelation_token` (cancels every run associated with the token) or `run_id` - (cancels a single tenant-scoped run). Supplying both or neither returns a `400`. - A `run_id` that does not match a run for the tenant returns `404`. Cancelation - is idempotent: a run that has already finished (`PROCESSED`/`ERROR`) or was - already `CANCELED` is left unchanged and its current status is returned. + """ + Cancels in-flight journey runs, either every run sharing a cancelation token or + one run by id. Use it to stop a sequence when the event resolves. Args: extra_headers: Send extra headers @@ -778,14 +748,9 @@ async def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CancelJourneyResponse: - """Cancel journey runs. - - The request body must include EXACTLY ONE of - `cancelation_token` (cancels every run associated with the token) or `run_id` - (cancels a single tenant-scoped run). Supplying both or neither returns a `400`. - A `run_id` that does not match a run for the tenant returns `404`. Cancelation - is idempotent: a run that has already finished (`PROCESSED`/`ERROR`) or was - already `CANCELED` is left unchanged and its current status is returned. + """ + Cancels in-flight journey runs, either every run sharing a cancelation token or + one run by id. Use it to stop a sequence when the event resolves. Args: extra_headers: Send extra headers @@ -845,10 +810,10 @@ async def invoke( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneysInvokeResponse: - """Invoke a journey by id or alias to start a new run. + """Starts a journey run for one user and returns a runId. - The response includes a - `runId` identifying the run. + Runs execute + asynchronously, so the response arrives before any message is sent. Args: data: Data payload passed to the journey. The expected shape can be predefined using @@ -904,7 +869,8 @@ async def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyVersionsListResponse: """ - List published versions of a journey, ordered most recent first. + Lists a journey's published versions, most recent first, so you have a version + id to roll back to. Paged by cursor. Args: extra_headers: Send extra headers @@ -937,11 +903,9 @@ async def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Publish the current draft as a new version. - - Body is optional; pass - `{ "version": "vN" }` to roll back to a prior version instead. Returns 404 if - the journey has no draft to publish. + """ + Publishes a journey's current draft as a new version, making it live for new + runs. Pass a version instead to roll back to an earlier one. Args: extra_headers: Send extra headers @@ -978,13 +942,9 @@ async def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyResponse: - """Replace the journey draft. - - Updates the working draft only; call - `POST /journeys/{templateId}/publish` to make it live, or pass - `state: "PUBLISHED"` in this request to publish immediately. Send-node - `template` ids must already exist and be scoped to this journey, and node ids - must not be claimed by another journey. + """ + Replaces a journey's working draft, leaving the published version live until you + publish. Reach for this when editing a journey already running. Args: state: Lifecycle state of a journey. diff --git a/src/courier/resources/journeys/templates.py b/src/courier/resources/journeys/templates.py index cb716dca..bb5ea256 100644 --- a/src/courier/resources/journeys/templates.py +++ b/src/courier/resources/journeys/templates.py @@ -117,11 +117,9 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyTemplateGetResponse: - """Fetch a journey-scoped notification template by id. - - Pass `?version=draft` - (default `published`) to retrieve the working draft, or `?version=vN` for a - historical version. + """ + Returns a journey's own notification template with its name, brand, subscription + topic, and content. Defaults to the published version. Args: extra_headers: Send extra headers @@ -211,10 +209,10 @@ def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive the journey-scoped notification template. + """Archives one journey's notification template, preventing further sends. - Archived templates cannot be - sent. + Detach + any send node referencing it beforehand. Args: extra_headers: Send extra headers @@ -255,8 +253,8 @@ def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateVersionListResponse: """ - List published versions of the journey-scoped notification template, ordered - most recent first. + Lists the published versions of a template that belongs to a journey, most + recent first. Paged by cursor. Args: extra_headers: Send extra headers @@ -296,10 +294,10 @@ def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Publish the current draft of the journey-scoped notification template as a new - version. Optionally roll back to a prior version by passing - `{ "version": "vN" }`. + """Publishes a journey-scoped template's draft as a new version. + + Pass a version + instead to roll back the template to an earlier publish. Args: extra_headers: Send extra headers @@ -455,8 +453,10 @@ def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyTemplateGetResponse: - """ - Replace the journey-scoped notification template draft. + """Replaces the draft content of one journey's notification template. + + Publish it + before send nodes referencing it render the change. Args: extra_headers: Send extra headers @@ -503,13 +503,9 @@ def retrieve_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentGetResponse: - """Retrieve the elemental content of a journey-scoped notification template. - - The - response contains the versioned elements along with their content checksums, - which can be used to detect changes between versions. Pass `?version=draft` - (default `published`) to retrieve the working draft, or `?version=vN` for a - historical version. + """ + Returns the Elemental elements and version of a journey-scoped template's + content. Compare versions to see what changed between publishes. Args: version: Accepts `draft`, `published`, or a version string (e.g., `v001`). Defaults to @@ -626,11 +622,9 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyTemplateGetResponse: - """Fetch a journey-scoped notification template by id. - - Pass `?version=draft` - (default `published`) to retrieve the working draft, or `?version=vN` for a - historical version. + """ + Returns a journey's own notification template with its name, brand, subscription + topic, and content. Defaults to the published version. Args: extra_headers: Send extra headers @@ -720,10 +714,10 @@ async def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive the journey-scoped notification template. + """Archives one journey's notification template, preventing further sends. - Archived templates cannot be - sent. + Detach + any send node referencing it beforehand. Args: extra_headers: Send extra headers @@ -764,8 +758,8 @@ async def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateVersionListResponse: """ - List published versions of the journey-scoped notification template, ordered - most recent first. + Lists the published versions of a template that belongs to a journey, most + recent first. Paged by cursor. Args: extra_headers: Send extra headers @@ -805,10 +799,10 @@ async def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Publish the current draft of the journey-scoped notification template as a new - version. Optionally roll back to a prior version by passing - `{ "version": "vN" }`. + """Publishes a journey-scoped template's draft as a new version. + + Pass a version + instead to roll back the template to an earlier publish. Args: extra_headers: Send extra headers @@ -964,8 +958,10 @@ async def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> JourneyTemplateGetResponse: - """ - Replace the journey-scoped notification template draft. + """Replaces the draft content of one journey's notification template. + + Publish it + before send nodes referencing it render the change. Args: extra_headers: Send extra headers @@ -1012,13 +1008,9 @@ async def retrieve_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentGetResponse: - """Retrieve the elemental content of a journey-scoped notification template. - - The - response contains the versioned elements along with their content checksums, - which can be used to detect changes between versions. Pass `?version=draft` - (default `published`) to retrieve the working draft, or `?version=vN` for a - historical version. + """ + Returns the Elemental elements and version of a journey-scoped template's + content. Compare versions to see what changed between publishes. Args: version: Accepts `draft`, `published`, or a version string (e.g., `v001`). Defaults to diff --git a/src/courier/resources/lists/lists.py b/src/courier/resources/lists/lists.py index ae71b29b..37063764 100644 --- a/src/courier/resources/lists/lists.py +++ b/src/courier/resources/lists/lists.py @@ -68,8 +68,10 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SubscriptionList: - """ - Returns a list based on the list ID provided. + """Returns one list by id with its name and created and updated timestamps. + + Fetch + its subscribers separately with the subscriptions endpoint. Args: extra_headers: Send extra headers @@ -103,8 +105,10 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Create or replace an existing list with the supplied values. + """Creates or replaces a list from a name and preferences. + + Subscribers are managed + through the separate subscriptions endpoints. Args: extra_headers: Send extra headers @@ -146,7 +150,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListListResponse: """ - Returns all of the lists, with the ability to filter based on a pattern. + Returns the workspace's lists, filterable by a pattern to fetch a subset such as + every regional list. Paged by cursor. Args: cursor: A unique identifier that allows for fetching the next page of lists. @@ -194,8 +199,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a list by list ID. + """Deletes a list, halting sends that target it. + + A previously deleted list can be + brought back with the companion restore endpoint. Args: extra_headers: Send extra headers @@ -229,7 +236,8 @@ def restore( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Restore a previously deleted list. + Restores a previously deleted list along with its subscribers, so a list removed + by mistake can be brought back rather than rebuilt. Args: extra_headers: Send extra headers @@ -287,8 +295,10 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SubscriptionList: - """ - Returns a list based on the list ID provided. + """Returns one list by id with its name and created and updated timestamps. + + Fetch + its subscribers separately with the subscriptions endpoint. Args: extra_headers: Send extra headers @@ -322,8 +332,10 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Create or replace an existing list with the supplied values. + """Creates or replaces a list from a name and preferences. + + Subscribers are managed + through the separate subscriptions endpoints. Args: extra_headers: Send extra headers @@ -365,7 +377,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListListResponse: """ - Returns all of the lists, with the ability to filter based on a pattern. + Returns the workspace's lists, filterable by a pattern to fetch a subset such as + every regional list. Paged by cursor. Args: cursor: A unique identifier that allows for fetching the next page of lists. @@ -413,8 +426,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a list by list ID. + """Deletes a list, halting sends that target it. + + A previously deleted list can be + brought back with the companion restore endpoint. Args: extra_headers: Send extra headers @@ -448,7 +463,8 @@ async def restore( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Restore a previously deleted list. + Restores a previously deleted list along with its subscribers, so a list removed + by mistake can be brought back rather than rebuilt. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/lists/subscriptions.py b/src/courier/resources/lists/subscriptions.py index 74034f4b..9d3cd1f0 100644 --- a/src/courier/resources/lists/subscriptions.py +++ b/src/courier/resources/lists/subscriptions.py @@ -63,7 +63,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SubscriptionListResponse: """ - Get the list's subscriptions. + Returns the users subscribed to a list with paging, each with the preferences + recorded for that subscription. Args: cursor: A unique identifier that allows for fetching the next set of list subscriptions @@ -179,8 +180,8 @@ def subscribe_user( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Subscribe a user to an existing list (note: if the List does not exist, it will - be automatically created). + Subscribes one user to a list, creating the list if it does not yet exist. + Optional preferences apply to this subscription only. Args: extra_headers: Send extra headers @@ -219,8 +220,10 @@ def unsubscribe_user( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a subscription to a list by list ID and user ID. + """Removes one user's subscription to a list, addressed by list id and user id. + + The + user's profile and other subscriptions are separate resources. Args: extra_headers: Send extra headers @@ -278,7 +281,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SubscriptionListResponse: """ - Get the list's subscriptions. + Returns the users subscribed to a list with paging, each with the preferences + recorded for that subscription. Args: cursor: A unique identifier that allows for fetching the next set of list subscriptions @@ -396,8 +400,8 @@ async def subscribe_user( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Subscribe a user to an existing list (note: if the List does not exist, it will - be automatically created). + Subscribes one user to a list, creating the list if it does not yet exist. + Optional preferences apply to this subscription only. Args: extra_headers: Send extra headers @@ -436,8 +440,10 @@ async def unsubscribe_user( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a subscription to a list by list ID and user ID. + """Removes one user's subscription to a list, addressed by list id and user id. + + The + user's profile and other subscriptions are separate resources. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/messages.py b/src/courier/resources/messages.py index c8c87ce9..10dbf259 100644 --- a/src/courier/resources/messages.py +++ b/src/courier/resources/messages.py @@ -60,7 +60,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageRetrieveResponse: """ - Fetch the status of a message you've previously sent. + Returns a sent message's status, recipient, event, and per-provider delivery + detail, with timestamps for enqueued, sent, delivered, opened, and clicked. Args: extra_headers: Send extra headers @@ -106,7 +107,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageListResponse: """ - Fetch the statuses of messages you've previously sent. + Returns previously sent messages, most recent first, each carrying its status, + recipient, channel, and provider. Paged by cursor. Args: archived: A boolean value that indicates whether archived messages should be included in @@ -195,13 +197,9 @@ def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageDetails: - """Cancel a message that is currently in the process of being delivered. - - A - well-formatted API call to the cancel message API will return either `200` - status code for a successful cancellation or `409` status code for an - unsuccessful cancellation. Both cases will include the actual message record in - the response body (see details below). + """ + Cancels a message that is still in the delivery pipeline and returns the message + record with its resulting canceled or failed status. Args: extra_headers: Send extra headers @@ -234,7 +232,8 @@ def content( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageContentResponse: """ - Get message content + Returns the rendered content Courier delivered for a message, broken out per + channel, to confirm what the recipient received. Args: extra_headers: Send extra headers @@ -268,7 +267,8 @@ def history( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageHistoryResponse: """ - Fetch the array of events of a message you've previously sent. + Returns the ordered event history for a sent message, one entry per status + transition with its timestamp. Args: type: A supported Message History type that will filter the events returned. @@ -306,13 +306,9 @@ def resend( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageResendResponse: - """Resend a previously sent message. - - The original send request is loaded from - storage and a brand-new send is enqueued for the same recipient and content, - producing a **new** `messageId` — the original message is not modified. - Throttled by a per-message rate limit; a repeat inside the limit window returns - `429 Too Many Requests`. + """ + Resends a previously sent message to the same recipient and content, returning a + new messageId. The original send request is not modified. Args: extra_headers: Send extra headers @@ -366,7 +362,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageRetrieveResponse: """ - Fetch the status of a message you've previously sent. + Returns a sent message's status, recipient, event, and per-provider delivery + detail, with timestamps for enqueued, sent, delivered, opened, and clicked. Args: extra_headers: Send extra headers @@ -412,7 +409,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageListResponse: """ - Fetch the statuses of messages you've previously sent. + Returns previously sent messages, most recent first, each carrying its status, + recipient, channel, and provider. Paged by cursor. Args: archived: A boolean value that indicates whether archived messages should be included in @@ -501,13 +499,9 @@ async def cancel( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageDetails: - """Cancel a message that is currently in the process of being delivered. - - A - well-formatted API call to the cancel message API will return either `200` - status code for a successful cancellation or `409` status code for an - unsuccessful cancellation. Both cases will include the actual message record in - the response body (see details below). + """ + Cancels a message that is still in the delivery pipeline and returns the message + record with its resulting canceled or failed status. Args: extra_headers: Send extra headers @@ -540,7 +534,8 @@ async def content( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageContentResponse: """ - Get message content + Returns the rendered content Courier delivered for a message, broken out per + channel, to confirm what the recipient received. Args: extra_headers: Send extra headers @@ -574,7 +569,8 @@ async def history( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageHistoryResponse: """ - Fetch the array of events of a message you've previously sent. + Returns the ordered event history for a sent message, one entry per status + transition with its timestamp. Args: type: A supported Message History type that will filter the events returned. @@ -612,13 +608,9 @@ async def resend( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> MessageResendResponse: - """Resend a previously sent message. - - The original send request is loaded from - storage and a brand-new send is enqueued for the same recipient and content, - producing a **new** `messageId` — the original message is not modified. - Throttled by a per-message rate limit; a repeat inside the limit window returns - `429 Too Many Requests`. + """ + Resends a previously sent message to the same recipient and content, returning a + new messageId. The original send request is not modified. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/notifications/checks.py b/src/courier/resources/notifications/checks.py index b619de48..4da0afe6 100644 --- a/src/courier/resources/notifications/checks.py +++ b/src/courier/resources/notifications/checks.py @@ -59,7 +59,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CheckUpdateResponse: """ - Replace the submission checks for a notification template. + Replaces the approval checks on a template submission with the complete set + supplied in the request body. Args: extra_headers: Send extra headers @@ -96,7 +97,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CheckListResponse: """ - Retrieve the submission checks for a notification template. + Returns the approval checks recorded for a template submission, each with its + pass or fail result. Args: extra_headers: Send extra headers @@ -131,8 +133,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Cancel a submission for a notification template. + """Cancels a pending template submission, withdrawing it from the approval + workflow. + + The template stays in draft and can be resubmitted later. Args: extra_headers: Send extra headers @@ -191,7 +195,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CheckUpdateResponse: """ - Replace the submission checks for a notification template. + Replaces the approval checks on a template submission with the complete set + supplied in the request body. Args: extra_headers: Send extra headers @@ -228,7 +233,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CheckListResponse: """ - Retrieve the submission checks for a notification template. + Returns the approval checks recorded for a template submission, each with its + pass or fail result. Args: extra_headers: Send extra headers @@ -263,8 +269,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Cancel a submission for a notification template. + """Cancels a pending template submission, withdrawing it from the approval + workflow. + + The template stays in draft and can be resubmitted later. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/notifications/notifications.py b/src/courier/resources/notifications/notifications.py index a479a76d..c6a6c1d5 100644 --- a/src/courier/resources/notifications/notifications.py +++ b/src/courier/resources/notifications/notifications.py @@ -177,8 +177,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationListResponse: - """ - List notification templates in your workspace. + """Lists the workspace's notification templates. + + Each carries a name, tags, brand, + routing, and its draft or published state. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. @@ -225,8 +227,10 @@ def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Archive a notification template. + """Archives a notification template, preventing new sends from referencing it. + + The + template stays retrievable for its version history. Args: extra_headers: Send extra headers @@ -259,14 +263,10 @@ def duplicate( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateResponse: - """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. + """ + Copies a notification template within the same workspace and environment, + appending " COPY" to the title. The copy is standalone and independently + editable. Args: extra_headers: Send extra headers @@ -301,7 +301,8 @@ def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateVersionListResponse: """ - List versions of a notification template. + Returns a notification template's published versions, most recent first, for + comparison or rollback. Paged. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. @@ -389,11 +390,10 @@ def put_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Replace the elemental content of a notification template. + """Replaces all Elemental content in a template, overwriting every existing + element. - Overwrites all - elements in the template with the provided content. Only supported for V2 - (elemental) templates. + Supported for V2 templates only, not V1 blocks and channels. Args: content: Elemental content payload. The server defaults `version` when omitted. @@ -444,10 +444,9 @@ def put_element( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Update a single element within a notification template. - - Only supported for V2 - (elemental) templates. + """ + Replaces one Elemental element in a template, addressed by its element id. + Supported for V2 templates only, not V1 blocks and channels. Args: type: Element type (text, meta, action, image, etc.). @@ -500,11 +499,10 @@ def put_locale( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Set locale-specific content overrides for a notification template. + """Sets locale-specific content overrides for a template. - Each element - override must reference an existing element by ID. Only supported for V2 - (elemental) templates. + Each override must + reference an element that already exists in the default content. Args: elements: Elements with locale-specific content overrides. @@ -551,9 +549,9 @@ def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateResponse: - """Replace a notification template. - - All fields are required. + """ + Replaces a notification template in full, so send every field rather than only + the ones you want changed. Publish separately to make it live. Args: notification: Core template fields used in POST and PUT request bodies (nested under a @@ -599,12 +597,10 @@ def retrieve_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationRetrieveContentResponse: - """Retrieve the content of a notification template. + """Returns a template's content and checksum. - The response shape depends on - whether the template uses V1 (blocks/channels) or V2 (elemental) content. Use - the `version` query parameter to select draft, published, or a specific - historical version. + V2 templates return Elemental + elements, while V1 templates return blocks and channels instead. Args: version: Accepts `draft`, `published`, or a version string (e.g., `v001`). Defaults to @@ -769,8 +765,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationListResponse: - """ - List notification templates in your workspace. + """Lists the workspace's notification templates. + + Each carries a name, tags, brand, + routing, and its draft or published state. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. @@ -817,8 +815,10 @@ async def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Archive a notification template. + """Archives a notification template, preventing new sends from referencing it. + + The + template stays retrievable for its version history. Args: extra_headers: Send extra headers @@ -851,14 +851,10 @@ async def duplicate( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateResponse: - """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. + """ + Copies a notification template within the same workspace and environment, + appending " COPY" to the title. The copy is standalone and independently + editable. Args: extra_headers: Send extra headers @@ -893,7 +889,8 @@ async def list_versions( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateVersionListResponse: """ - List versions of a notification template. + Returns a notification template's published versions, most recent first, for + comparison or rollback. Paged. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. @@ -983,11 +980,10 @@ async def put_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Replace the elemental content of a notification template. + """Replaces all Elemental content in a template, overwriting every existing + element. - Overwrites all - elements in the template with the provided content. Only supported for V2 - (elemental) templates. + Supported for V2 templates only, not V1 blocks and channels. Args: content: Elemental content payload. The server defaults `version` when omitted. @@ -1038,10 +1034,9 @@ async def put_element( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Update a single element within a notification template. - - Only supported for V2 - (elemental) templates. + """ + Replaces one Elemental element in a template, addressed by its element id. + Supported for V2 templates only, not V1 blocks and channels. Args: type: Element type (text, meta, action, image, etc.). @@ -1094,11 +1089,10 @@ async def put_locale( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationContentMutationResponse: - """Set locale-specific content overrides for a notification template. + """Sets locale-specific content overrides for a template. - Each element - override must reference an existing element by ID. Only supported for V2 - (elemental) templates. + Each override must + reference an element that already exists in the default content. Args: elements: Elements with locale-specific content overrides. @@ -1145,9 +1139,9 @@ async def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationTemplateResponse: - """Replace a notification template. - - All fields are required. + """ + Replaces a notification template in full, so send every field rather than only + the ones you want changed. Publish separately to make it live. Args: notification: Core template fields used in POST and PUT request bodies (nested under a @@ -1193,12 +1187,10 @@ async def retrieve_content( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> NotificationRetrieveContentResponse: - """Retrieve the content of a notification template. + """Returns a template's content and checksum. - The response shape depends on - whether the template uses V1 (blocks/channels) or V2 (elemental) content. Use - the `version` query parameter to select draft, published, or a specific - historical version. + V2 templates return Elemental + elements, while V1 templates return blocks and channels instead. Args: version: Accepts `draft`, `published`, or a version string (e.g., `v001`). Defaults to diff --git a/src/courier/resources/profiles/lists.py b/src/courier/resources/profiles/lists.py index 4f41eb9d..8cab7b03 100644 --- a/src/courier/resources/profiles/lists.py +++ b/src/courier/resources/profiles/lists.py @@ -58,8 +58,10 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListRetrieveResponse: - """ - Returns the subscribed lists for a specified user. + """Returns the lists a user is subscribed to, with paging. + + Use it to check what a + recipient will receive before sending to a list. Args: cursor: A unique identifier that allows for fetching the next set of message statuses. @@ -97,8 +99,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListDeleteResponse: - """ - Removes all list subscriptions for given user. + """Removes every list subscription for a user at once. + + Their profile and + preferences are untouched, so this only affects list-targeted sends. Args: extra_headers: Send extra headers @@ -131,10 +135,9 @@ def subscribe( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListSubscribeResponse: - """Subscribes the given user to one or more lists. - - If the list does not exist, it - will be created. + """ + Subscribes a user to one or more lists, creating any list that does not yet + exist. Optional preferences apply to each subscription. Args: extra_headers: Send extra headers @@ -189,8 +192,10 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListRetrieveResponse: - """ - Returns the subscribed lists for a specified user. + """Returns the lists a user is subscribed to, with paging. + + Use it to check what a + recipient will receive before sending to a list. Args: cursor: A unique identifier that allows for fetching the next set of message statuses. @@ -228,8 +233,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListDeleteResponse: - """ - Removes all list subscriptions for given user. + """Removes every list subscription for a user at once. + + Their profile and + preferences are untouched, so this only affects list-targeted sends. Args: extra_headers: Send extra headers @@ -262,10 +269,9 @@ async def subscribe( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ListSubscribeResponse: - """Subscribes the given user to one or more lists. - - If the list does not exist, it - will be created. + """ + Subscribes a user to one or more lists, creating any list that does not yet + exist. Optional preferences apply to each subscription. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/profiles/profiles.py b/src/courier/resources/profiles/profiles.py index d359fbc1..51fea6c3 100644 --- a/src/courier/resources/profiles/profiles.py +++ b/src/courier/resources/profiles/profiles.py @@ -70,8 +70,8 @@ def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileCreateResponse: """ - Merge the supplied values with an existing profile or create a new profile if - one doesn't already exist. + Merges the supplied values into a user's profile, creating it if absent and + leaving any key you omit untouched. Prefer this for everyday writes. Args: extra_headers: Send extra headers @@ -105,7 +105,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileRetrieveResponse: """ - Returns the specified user profile. + Returns a user's stored profile and preferences, including the email address, + phone number, and push tokens Courier can reach them on. Args: extra_headers: Send extra headers @@ -139,7 +140,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Update a profile + Applies a JSON Patch to a user profile, adding, removing, or replacing + individual fields without sending the whole object. Args: patch: List of patch operations to apply to the profile. @@ -175,8 +177,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Deletes the specified user profile. + """Deletes a user's profile and stored contact details. + + List subscriptions and + preferences are separate resources, so remove those too if required. Args: extra_headers: Send extra headers @@ -210,12 +214,10 @@ def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileReplaceResponse: - """ - When using `PUT`, be sure to include all the key-value pairs required by the - recipient's profile. Any key-value pairs that exist in the profile but fail to - be included in the `PUT` request will be removed from the profile. Remember, a - `PUT` update is a full replacement of the data. For partial updates, use the - [Patch](https://www.courier.com/docs/reference/profiles/patch/) request. + """Overwrites a user profile in full, removing any key absent from the request + body. + + Use the patch endpoint when changing a single field. Args: extra_headers: Send extra headers @@ -275,8 +277,8 @@ async def create( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileCreateResponse: """ - Merge the supplied values with an existing profile or create a new profile if - one doesn't already exist. + Merges the supplied values into a user's profile, creating it if absent and + leaving any key you omit untouched. Prefer this for everyday writes. Args: extra_headers: Send extra headers @@ -310,7 +312,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileRetrieveResponse: """ - Returns the specified user profile. + Returns a user's stored profile and preferences, including the email address, + phone number, and push tokens Courier can reach them on. Args: extra_headers: Send extra headers @@ -344,7 +347,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Update a profile + Applies a JSON Patch to a user profile, adding, removing, or replacing + individual fields without sending the whole object. Args: patch: List of patch operations to apply to the profile. @@ -380,8 +384,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Deletes the specified user profile. + """Deletes a user's profile and stored contact details. + + List subscriptions and + preferences are separate resources, so remove those too if required. Args: extra_headers: Send extra headers @@ -415,12 +421,10 @@ async def replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProfileReplaceResponse: - """ - When using `PUT`, be sure to include all the key-value pairs required by the - recipient's profile. Any key-value pairs that exist in the profile but fail to - be included in the `PUT` request will be removed from the profile. Remember, a - `PUT` update is a full replacement of the data. For partial updates, use the - [Patch](https://www.courier.com/docs/reference/profiles/patch/) request. + """Overwrites a user profile in full, removing any key absent from the request + body. + + Use the patch endpoint when changing a single field. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/providers/catalog.py b/src/courier/resources/providers/catalog.py index d89a86c0..3587b36c 100644 --- a/src/courier/resources/providers/catalog.py +++ b/src/courier/resources/providers/catalog.py @@ -55,10 +55,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: """ - Returns the catalog of available provider types with their display names, - descriptions, and configuration schema fields (snake_case, with `type` and - `required`). Providers with no configurable schema return only `provider`, - `name`, and `description`. + Returns the provider types Courier supports, each with a display name, + description, and the configuration fields it requires. Args: channel: Exact match (case-insensitive) against the provider channel taxonomy (e.g. @@ -130,10 +128,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> CatalogListResponse: """ - Returns the catalog of available provider types with their display names, - descriptions, and configuration schema fields (snake_case, with `type` and - `required`). Providers with no configurable schema return only `provider`, - `name`, and `description`. + Returns the provider types Courier supports, each with a display name, + description, and the configuration fields it requires. Args: channel: Exact match (case-insensitive) against the provider channel taxonomy (e.g. diff --git a/src/courier/resources/providers/providers.py b/src/courier/resources/providers/providers.py index 57bc9da5..b2b6a481 100644 --- a/src/courier/resources/providers/providers.py +++ b/src/courier/resources/providers/providers.py @@ -70,10 +70,9 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: - """Create a new provider configuration. - - The `provider` field must be a known - Courier provider key (see catalog). + """ + Configures a provider integration from a Courier provider key and its settings. + Check the catalog endpoint for the schema each provider expects. Args: provider: The provider key identifying the type (e.g. "sendgrid", "twilio"). Must be a @@ -124,7 +123,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: """ - Fetch a single provider configuration by ID. + Returns one configured provider by id, including its channel, provider key, + alias, title, and current settings. Args: extra_headers: Send extra headers @@ -160,13 +160,9 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: - """Replace an existing provider configuration. - - The `provider` key is required and - determines which provider-specific settings schema is applied. All other fields - are optional — omitted fields are cleared from the stored configuration (this is - a full replacement, not a partial merge). Changing the provider type for an - existing configuration is not supported. + """ + Replaces a provider's configuration in full, clearing any field you omit rather + than merging it. Send the complete settings object. Args: provider: The provider key identifying the type. Required on every request because it @@ -218,10 +214,9 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProviderListResponse: - """List configured provider integrations for the current workspace. - - Supports - cursor-based pagination. + """ + Lists the provider integrations configured in the workspace, one entry per + channel and provider key with its alias and settings. Args: cursor: Opaque cursor for fetching the next page. @@ -257,10 +252,9 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Delete a provider configuration. - - Returns 409 if the provider is still referenced - by routing or notifications. + """ + Deletes a provider configuration, which fails while routing strategies or + templates still reference it. Update those references first. Args: extra_headers: Send extra headers @@ -321,10 +315,9 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: - """Create a new provider configuration. - - The `provider` field must be a known - Courier provider key (see catalog). + """ + Configures a provider integration from a Courier provider key and its settings. + Check the catalog endpoint for the schema each provider expects. Args: provider: The provider key identifying the type (e.g. "sendgrid", "twilio"). Must be a @@ -375,7 +368,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: """ - Fetch a single provider configuration by ID. + Returns one configured provider by id, including its channel, provider key, + alias, title, and current settings. Args: extra_headers: Send extra headers @@ -411,13 +405,9 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Provider: - """Replace an existing provider configuration. - - The `provider` key is required and - determines which provider-specific settings schema is applied. All other fields - are optional — omitted fields are cleared from the stored configuration (this is - a full replacement, not a partial merge). Changing the provider type for an - existing configuration is not supported. + """ + Replaces a provider's configuration in full, clearing any field you omit rather + than merging it. Send the complete settings object. Args: provider: The provider key identifying the type. Required on every request because it @@ -469,10 +459,9 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> ProviderListResponse: - """List configured provider integrations for the current workspace. - - Supports - cursor-based pagination. + """ + Lists the provider integrations configured in the workspace, one entry per + channel and provider key with its alias and settings. Args: cursor: Opaque cursor for fetching the next page. @@ -508,10 +497,9 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Delete a provider configuration. - - Returns 409 if the provider is still referenced - by routing or notifications. + """ + Deletes a provider configuration, which fails while routing strategies or + templates still reference it. Update those references first. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/requests.py b/src/courier/resources/requests.py index c2ddf98b..4b94972b 100644 --- a/src/courier/resources/requests.py +++ b/src/courier/resources/requests.py @@ -50,8 +50,10 @@ def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Archive message + """Archives a send request by its request id. + + Use it to remove test sends or + superseded requests from the message list without deleting them. Args: extra_headers: Send extra headers @@ -105,8 +107,10 @@ async def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Archive message + """Archives a send request by its request id. + + Use it to remove test sends or + superseded requests from the message list without deleting them. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/routing_strategies.py b/src/courier/resources/routing_strategies.py index 99910979..bdcfbf01 100644 --- a/src/courier/resources/routing_strategies.py +++ b/src/courier/resources/routing_strategies.py @@ -125,10 +125,9 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RoutingStrategyGetResponse: - """Retrieve a routing strategy by ID. - - Returns the full entity including routing - content and metadata. + """ + Returns one routing strategy by id with its name, tags, channels, and the + routing rules that decide provider order and fallback. Args: extra_headers: Send extra headers @@ -247,10 +246,10 @@ def list_notifications( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AssociatedNotificationListResponse: - """List notification templates associated with a routing strategy. + """Returns the notification templates using a routing strategy, with paging. - Includes - template metadata only, not full content. + Check + this before changing a strategy that templates depend on. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. @@ -442,10 +441,9 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> RoutingStrategyGetResponse: - """Retrieve a routing strategy by ID. - - Returns the full entity including routing - content and metadata. + """ + Returns one routing strategy by id with its name, tags, channels, and the + routing rules that decide provider order and fallback. Args: extra_headers: Send extra headers @@ -564,10 +562,10 @@ async def list_notifications( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> AssociatedNotificationListResponse: - """List notification templates associated with a routing strategy. + """Returns the notification templates using a routing strategy, with paging. - Includes - template metadata only, not full content. + Check + this before changing a strategy that templates depend on. Args: cursor: Opaque pagination cursor from a previous response. Omit for the first page. diff --git a/src/courier/resources/send.py b/src/courier/resources/send.py index 21c8cbe8..212a1dc8 100644 --- a/src/courier/resources/send.py +++ b/src/courier/resources/send.py @@ -52,8 +52,10 @@ def message( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SendMessageResponse: - """ - Send a message to one or more recipients. + """Sends a message to one or more recipients and returns a requestId. + + Courier + routes it to email, SMS, push, chat, or in-app based on your rules. Args: message: The message property has the following primary top-level properties. They define @@ -108,8 +110,10 @@ async def message( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> SendMessageResponse: - """ - Send a message to one or more recipients. + """Sends a message to one or more recipients and returns a requestId. + + Courier + routes it to email, SMS, push, chat, or in-app based on your rules. Args: message: The message property has the following primary top-level properties. They define diff --git a/src/courier/resources/tenants/preferences/items.py b/src/courier/resources/tenants/preferences/items.py index 91d35dc4..4e0f397d 100644 --- a/src/courier/resources/tenants/preferences/items.py +++ b/src/courier/resources/tenants/preferences/items.py @@ -60,7 +60,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Create or Replace Default Preferences For Topic + Sets a tenant's default opt-in status for one subscription topic, which applies + to every member unless a user sets their own override. Args: custom_routing: The default channels to send to this tenant when has_custom_routing is enabled @@ -113,7 +114,8 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Remove Default Preferences For Topic + Removes a tenant's default preference for one subscription topic, addressed by + tenant id and topic id. Args: extra_headers: Send extra headers @@ -176,7 +178,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Create or Replace Default Preferences For Topic + Sets a tenant's default opt-in status for one subscription topic, which applies + to every member unless a user sets their own override. Args: custom_routing: The default channels to send to this tenant when has_custom_routing is enabled @@ -229,7 +232,8 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Remove Default Preferences For Topic + Removes a tenant's default preference for one subscription topic, addressed by + tenant id and topic id. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/tenants/templates/templates.py b/src/courier/resources/tenants/templates/templates.py index accb1275..e617ec2b 100644 --- a/src/courier/resources/tenants/templates/templates.py +++ b/src/courier/resources/tenants/templates/templates.py @@ -72,7 +72,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BaseTemplateTenantAssociation: """ - Get a Template in Tenant + Returns a tenant's notification template with its content, version, and created, + updated, and published timestamps. Args: extra_headers: Send extra headers @@ -109,7 +110,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TemplateListResponse: """ - List Templates in Tenant + Lists a tenant's notification templates, each carrying its version and published + timestamp. Paged. Args: cursor: Continue the pagination with the next cursor @@ -156,13 +158,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Deletes the tenant's notification template with the given `template_id`. - - Returns **204 No Content** with an empty body on success. + """Deletes a tenant's notification template by id. - Returns **404** if there is no template with this ID for the tenant, including a - second `DELETE` after a successful removal. + Sends for that tenant then use + the workspace template registered under the same id. Args: extra_headers: Send extra headers @@ -200,10 +199,8 @@ def publish( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PostTenantTemplatePublishResponse: """ - Publishes a specific version of a notification template for a tenant. - - The template must already exist in the tenant's notification map. If no version - is specified, defaults to publishing the "latest" version. + Publishes a version of a tenant's notification template, making it the content + that tenant's sends render from until you publish another. Args: version: The version of the template to publish (e.g., "v1", "v2", "latest"). If not @@ -247,13 +244,8 @@ def replace( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PutTenantTemplateResponse: """ - Creates or updates a notification template for a tenant. - - If the template already exists for the tenant, it will be updated (200). - Otherwise, a new template is created (201). - - Optionally publishes the template immediately if the `published` flag is set to - true. + Creates or updates a notification template scoped to one tenant, letting a + tenant override the content the workspace template would send. Args: template: Template configuration for creating or updating a tenant notification template @@ -327,7 +319,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BaseTemplateTenantAssociation: """ - Get a Template in Tenant + Returns a tenant's notification template with its content, version, and created, + updated, and published timestamps. Args: extra_headers: Send extra headers @@ -364,7 +357,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TemplateListResponse: """ - List Templates in Tenant + Lists a tenant's notification templates, each carrying its version and published + timestamp. Paged. Args: cursor: Continue the pagination with the next cursor @@ -411,13 +405,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Deletes the tenant's notification template with the given `template_id`. - - Returns **204 No Content** with an empty body on success. + """Deletes a tenant's notification template by id. - Returns **404** if there is no template with this ID for the tenant, including a - second `DELETE` after a successful removal. + Sends for that tenant then use + the workspace template registered under the same id. Args: extra_headers: Send extra headers @@ -455,10 +446,8 @@ async def publish( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PostTenantTemplatePublishResponse: """ - Publishes a specific version of a notification template for a tenant. - - The template must already exist in the tenant's notification map. If no version - is specified, defaults to publishing the "latest" version. + Publishes a version of a tenant's notification template, making it the content + that tenant's sends render from until you publish another. Args: version: The version of the template to publish (e.g., "v1", "v2", "latest"). If not @@ -502,13 +491,8 @@ async def replace( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PutTenantTemplateResponse: """ - Creates or updates a notification template for a tenant. - - If the template already exists for the tenant, it will be updated (200). - Otherwise, a new template is created (201). - - Optionally publishes the template immediately if the `published` flag is set to - true. + Creates or updates a notification template scoped to one tenant, letting a + tenant override the content the workspace template would send. Args: template: Template configuration for creating or updating a tenant notification template diff --git a/src/courier/resources/tenants/templates/versions.py b/src/courier/resources/tenants/templates/versions.py index 8b941609..8b33fe1e 100644 --- a/src/courier/resources/tenants/templates/versions.py +++ b/src/courier/resources/tenants/templates/versions.py @@ -54,13 +54,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BaseTemplateTenantAssociation: """ - Fetches a specific version of a tenant template. - - Supports the following version formats: - - - `latest` - The most recent version of the template - - `published` - The currently published version - - `v{version}` - A specific version (e.g., "v1", "v2", "v1.0.0") + Returns one version of a tenant template, addressed by version number or by + latest, with its content and publish timestamp. Args: extra_headers: Send extra headers @@ -125,13 +120,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> BaseTemplateTenantAssociation: """ - Fetches a specific version of a tenant template. - - Supports the following version formats: - - - `latest` - The most recent version of the template - - `published` - The currently published version - - `v{version}` - A specific version (e.g., "v1", "v2", "v1.0.0") + Returns one version of a tenant template, addressed by version number or by + latest, with its content and publish timestamp. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/tenants/tenants.py b/src/courier/resources/tenants/tenants.py index 1c0d55b9..5d60c53d 100644 --- a/src/courier/resources/tenants/tenants.py +++ b/src/courier/resources/tenants/tenants.py @@ -82,7 +82,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Tenant: """ - Get a Tenant + Returns one tenant with its name, parent tenant id, default preferences, + properties, and the user profile applied to its members. Args: extra_headers: Send extra headers @@ -121,7 +122,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Tenant: """ - Create or Replace a Tenant + Creates or replaces a tenant from a name, parent, brand, properties, and default + preferences supplied in the request body. Args: name: Name of the tenant. @@ -180,7 +182,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListResponse: """ - Get a List of Tenants + Lists the workspace's tenants, each carrying a name, parent tenant, properties, + and default preferences. Paged. Args: cursor: Continue the pagination with the next cursor @@ -227,8 +230,10 @@ def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a Tenant + """Deletes a tenant. + + Its members' workspace-level profiles and preferences live + outside the tenant and are managed separately. Args: extra_headers: Send extra headers @@ -263,8 +268,10 @@ def list_users( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListUsersResponse: - """ - Get Users in Tenant + """Returns the users belonging to a tenant with cursor paging. + + Use it to see who a + tenant-scoped send will reach. Args: cursor: Continue the pagination with the next cursor @@ -340,7 +347,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Tenant: """ - Get a Tenant + Returns one tenant with its name, parent tenant id, default preferences, + properties, and the user profile applied to its members. Args: extra_headers: Send extra headers @@ -379,7 +387,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> Tenant: """ - Create or Replace a Tenant + Creates or replaces a tenant from a name, parent, brand, properties, and default + preferences supplied in the request body. Args: name: Name of the tenant. @@ -438,7 +447,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListResponse: """ - Get a List of Tenants + Lists the workspace's tenants, each carrying a name, parent tenant, properties, + and default preferences. Paged. Args: cursor: Continue the pagination with the next cursor @@ -485,8 +495,10 @@ async def delete( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Delete a Tenant + """Deletes a tenant. + + Its members' workspace-level profiles and preferences live + outside the tenant and are managed separately. Args: extra_headers: Send extra headers @@ -521,8 +533,10 @@ async def list_users( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListUsersResponse: - """ - Get Users in Tenant + """Returns the users belonging to a tenant with cursor paging. + + Use it to see who a + tenant-scoped send will reach. Args: cursor: Continue the pagination with the next cursor diff --git a/src/courier/resources/translations.py b/src/courier/resources/translations.py index f4b1cfd9..da61bc77 100644 --- a/src/courier/resources/translations.py +++ b/src/courier/resources/translations.py @@ -53,7 +53,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Get translations by locale + Returns the translation strings stored for one domain and locale, for use in + localized notification content. Args: extra_headers: Send extra headers @@ -89,8 +90,10 @@ def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Update a translation + """Uploads the translation strings for one domain and locale. + + Courier uses them to + render localized content for recipients in that locale. Args: extra_headers: Send extra headers @@ -149,7 +152,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> str: """ - Get translations by locale + Returns the translation strings stored for one domain and locale, for use in + localized notification content. Args: extra_headers: Send extra headers @@ -185,8 +189,10 @@ async def update( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Update a translation + """Uploads the translation strings for one domain and locale. + + Courier uses them to + render localized content for recipients in that locale. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/users/preferences.py b/src/courier/resources/users/preferences.py index 27e74a1d..be363dcc 100644 --- a/src/courier/resources/users/preferences.py +++ b/src/courier/resources/users/preferences.py @@ -67,7 +67,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceRetrieveResponse: """ - Fetch all user preferences. + Returns a user's preference overrides with paging, one entry per subscription + topic they have set a choice for. Args: tenant_id: Query the preferences of a user for this specific tenant context. @@ -107,25 +108,10 @@ def bulk_replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceBulkReplaceResponse: - """Replace a user's complete set of preference overrides in a single request. - - The - topics in the request body become the recipient's entire set of overrides: - listed topics are created or updated, and every existing override that is not - included in the body is reset to its topic default. Submitting an empty `topics` - array is a valid clear-all that resets every existing override. - - This operation is validation-atomic (all-or-nothing): structural validation - fails fast with a single `400`, and if any topic is semantically invalid (an - unknown topic, a `REQUIRED` topic that cannot be opted out, or a custom routing - request that is not available on the workspace's plan) the request returns a - single `400` aggregating every failure in `errors` and writes nothing. On - success it returns `200` with `items` (the complete resulting override set) and - `deleted` (the ids of the overrides that were reset to default). - - Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is - returned in Courier's canonical topic id form, regardless of the form supplied - in the request. + """Replaces a user's entire set of preference overrides. + + Any topic you leave out is + reset to its default, so send the full set rather than a subset. Args: topics: The complete set of topic overrides for the user. Up to 50 topics may be @@ -173,23 +159,8 @@ def bulk_update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceBulkUpdateResponse: """ - Additively create or update a user's preferences for one or more subscription - topics in a single request. Only the topics included in the request body are - created or updated; any existing overrides for topics not listed are left - untouched. - - Structural validation of the request body fails fast with a single `400`. Beyond - that, each topic is processed independently (partial-success, not - all-or-nothing): valid topics are written and returned in `items`, while topics - that cannot be applied are collected in `errors` with a per-topic `reason` (for - example an unknown topic, a `REQUIRED` topic that cannot be opted out, a custom - routing request that is not available on the workspace's plan, or a write - failure). The request therefore returns `200` with both lists whenever the body - is structurally valid. - - Every `topic_id` in the response — in both `items` and `errors` — is returned in - Courier's canonical topic id form, regardless of the form supplied in the - request. + Adds or updates a user's preferences for several subscription topics at once. + Topics you leave out keep whatever they were set to before. Args: topics: The topics to create or update. Between 1 and 50 topics may be provided in a @@ -236,9 +207,8 @@ def delete_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Remove a user's preferences for a specific subscription topic, resetting the - topic to its effective default. This operation is idempotent: deleting a - preference that does not exist succeeds with no error. + Removes a user's override for one subscription topic, resetting it to the + effective default from the tenant or workspace. Args: tenant_id: Delete the preferences of a user for this specific tenant context. @@ -284,7 +254,8 @@ def retrieve_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceRetrieveTopicResponse: """ - Fetch user preferences for a specific subscription topic. + Returns a user's opt-in status and channel choices for one subscription topic, + or the effective default if they have set no override. Args: tenant_id: Query the preferences of a user for this specific tenant context. @@ -330,7 +301,8 @@ def update_or_create_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceUpdateOrCreateTopicResponse: """ - Update or Create user preferences for a specific subscription topic. + Sets a user's opt-in status and channel choices for one subscription topic, + overriding the tenant default for that topic only. Args: tenant_id: Update the preferences of a user for this specific tenant context. @@ -399,7 +371,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceRetrieveResponse: """ - Fetch all user preferences. + Returns a user's preference overrides with paging, one entry per subscription + topic they have set a choice for. Args: tenant_id: Query the preferences of a user for this specific tenant context. @@ -441,25 +414,10 @@ async def bulk_replace( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceBulkReplaceResponse: - """Replace a user's complete set of preference overrides in a single request. - - The - topics in the request body become the recipient's entire set of overrides: - listed topics are created or updated, and every existing override that is not - included in the body is reset to its topic default. Submitting an empty `topics` - array is a valid clear-all that resets every existing override. - - This operation is validation-atomic (all-or-nothing): structural validation - fails fast with a single `400`, and if any topic is semantically invalid (an - unknown topic, a `REQUIRED` topic that cannot be opted out, or a custom routing - request that is not available on the workspace's plan) the request returns a - single `400` aggregating every failure in `errors` and writes nothing. On - success it returns `200` with `items` (the complete resulting override set) and - `deleted` (the ids of the overrides that were reset to default). - - Every `topic_id` in the response — in `items`, `deleted`, and any `errors` — is - returned in Courier's canonical topic id form, regardless of the form supplied - in the request. + """Replaces a user's entire set of preference overrides. + + Any topic you leave out is + reset to its default, so send the full set rather than a subset. Args: topics: The complete set of topic overrides for the user. Up to 50 topics may be @@ -509,23 +467,8 @@ async def bulk_update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceBulkUpdateResponse: """ - Additively create or update a user's preferences for one or more subscription - topics in a single request. Only the topics included in the request body are - created or updated; any existing overrides for topics not listed are left - untouched. - - Structural validation of the request body fails fast with a single `400`. Beyond - that, each topic is processed independently (partial-success, not - all-or-nothing): valid topics are written and returned in `items`, while topics - that cannot be applied are collected in `errors` with a per-topic `reason` (for - example an unknown topic, a `REQUIRED` topic that cannot be opted out, a custom - routing request that is not available on the workspace's plan, or a write - failure). The request therefore returns `200` with both lists whenever the body - is structurally valid. - - Every `topic_id` in the response — in both `items` and `errors` — is returned in - Courier's canonical topic id form, regardless of the form supplied in the - request. + Adds or updates a user's preferences for several subscription topics at once. + Topics you leave out keep whatever they were set to before. Args: topics: The topics to create or update. Between 1 and 50 topics may be provided in a @@ -574,9 +517,8 @@ async def delete_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Remove a user's preferences for a specific subscription topic, resetting the - topic to its effective default. This operation is idempotent: deleting a - preference that does not exist succeeds with no error. + Removes a user's override for one subscription topic, resetting it to the + effective default from the tenant or workspace. Args: tenant_id: Delete the preferences of a user for this specific tenant context. @@ -622,7 +564,8 @@ async def retrieve_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceRetrieveTopicResponse: """ - Fetch user preferences for a specific subscription topic. + Returns a user's opt-in status and channel choices for one subscription topic, + or the effective default if they have set no override. Args: tenant_id: Query the preferences of a user for this specific tenant context. @@ -668,7 +611,8 @@ async def update_or_create_topic( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PreferenceUpdateOrCreateTopicResponse: """ - Update or Create user preferences for a specific subscription topic. + Sets a user's opt-in status and channel choices for one subscription topic, + overriding the tenant default for that topic only. Args: tenant_id: Update the preferences of a user for this specific tenant context. diff --git a/src/courier/resources/users/tenants.py b/src/courier/resources/users/tenants.py index 64b9fb56..1b958f7d 100644 --- a/src/courier/resources/users/tenants.py +++ b/src/courier/resources/users/tenants.py @@ -57,8 +57,10 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListResponse: - """ - Returns a paginated list of user tenant associations. + """Returns the tenants a user belongs to, with cursor paging. + + A user can belong to + many tenants, each with its own profile and preferences. Args: cursor: Continue the pagination with the next cursor @@ -105,11 +107,9 @@ def add_multiple( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """This endpoint is used to add a user to multiple tenants in one call. - - A custom - profile can also be supplied for each tenant. This profile will be merged with - the user's main profile when sending to the user with that tenant. + """ + Adds a user to several tenants in one call, each optionally with a per-tenant + profile that overrides their workspace profile. Args: extra_headers: Send extra headers @@ -146,10 +146,8 @@ def add_single( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - This endpoint is used to add a single tenant. - - A custom profile can also be supplied with the tenant. This profile will be - merged with the user's main profile when sending to the user with that tenant. + Adds a user to one tenant, optionally with a tenant-specific profile that + overrides their workspace profile for sends in that tenant. Args: extra_headers: Send extra headers @@ -185,8 +183,10 @@ def remove_all( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Removes a user from any tenants they may have been associated with. + """Removes a user from every tenant they belong to in one call. + + Their + workspace-level profile is a separate resource. Args: extra_headers: Send extra headers @@ -220,8 +220,10 @@ def remove_single( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Removes a user from the supplied tenant. + """Removes a user from one tenant. + + Their other tenant memberships and workspace + profile are managed through separate endpoints. Args: extra_headers: Send extra headers @@ -279,8 +281,10 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TenantListResponse: - """ - Returns a paginated list of user tenant associations. + """Returns the tenants a user belongs to, with cursor paging. + + A user can belong to + many tenants, each with its own profile and preferences. Args: cursor: Continue the pagination with the next cursor @@ -327,11 +331,9 @@ async def add_multiple( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """This endpoint is used to add a user to multiple tenants in one call. - - A custom - profile can also be supplied for each tenant. This profile will be merged with - the user's main profile when sending to the user with that tenant. + """ + Adds a user to several tenants in one call, each optionally with a per-tenant + profile that overrides their workspace profile. Args: extra_headers: Send extra headers @@ -368,10 +370,8 @@ async def add_single( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - This endpoint is used to add a single tenant. - - A custom profile can also be supplied with the tenant. This profile will be - merged with the user's main profile when sending to the user with that tenant. + Adds a user to one tenant, optionally with a tenant-specific profile that + overrides their workspace profile for sends in that tenant. Args: extra_headers: Send extra headers @@ -407,8 +407,10 @@ async def remove_all( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Removes a user from any tenants they may have been associated with. + """Removes a user from every tenant they belong to in one call. + + Their + workspace-level profile is a separate resource. Args: extra_headers: Send extra headers @@ -442,8 +444,10 @@ async def remove_single( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """ - Removes a user from the supplied tenant. + """Removes a user from one tenant. + + Their other tenant memberships and workspace + profile are managed through separate endpoints. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/users/tokens.py b/src/courier/resources/users/tokens.py index 964065af..ef065605 100644 --- a/src/courier/resources/users/tokens.py +++ b/src/courier/resources/users/tokens.py @@ -58,7 +58,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TokenRetrieveResponse: """ - Get single token available for a `:token` + Returns one device token with its provider key, status and status reason, expiry + date, and any properties stored alongside it. Args: extra_headers: Send extra headers @@ -95,7 +96,8 @@ def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Apply a JSON Patch (RFC 6902) to the specified token. + Applies a JSON Patch to a device token, changing its status, expiry, or + properties without re-registering it. Args: extra_headers: Send extra headers @@ -132,7 +134,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TokenListResponse: """ - Gets all tokens available for a :user_id + Returns every device token registered for a user, each with its provider key, + status, and expiry date. Args: extra_headers: Send extra headers @@ -166,7 +169,8 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Delete User Token + Deletes one device token for a user, addressed by the token value, so push sends + no longer target that device. Args: extra_headers: Send extra headers @@ -202,7 +206,8 @@ def add_multiple( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Adds multiple tokens to a user and overwrites matching existing tokens. + Registers several device tokens for a user in one call, overwriting any stored + token with a matching value. Args: extra_headers: Send extra headers @@ -242,7 +247,8 @@ def add_single( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Adds a single token to a user and overwrites a matching existing token. + Registers one device token for a user against a provider key, overwriting the + token if it already exists. Push sends resolve tokens per user. Args: device: Information about the device the token came from. @@ -319,7 +325,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TokenRetrieveResponse: """ - Get single token available for a `:token` + Returns one device token with its provider key, status and status reason, expiry + date, and any properties stored alongside it. Args: extra_headers: Send extra headers @@ -356,7 +363,8 @@ async def update( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Apply a JSON Patch (RFC 6902) to the specified token. + Applies a JSON Patch to a device token, changing its status, expiry, or + properties without re-registering it. Args: extra_headers: Send extra headers @@ -393,7 +401,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> TokenListResponse: """ - Gets all tokens available for a :user_id + Returns every device token registered for a user, each with its provider key, + status, and expiry date. Args: extra_headers: Send extra headers @@ -427,7 +436,8 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Delete User Token + Deletes one device token for a user, addressed by the token value, so push sends + no longer target that device. Args: extra_headers: Send extra headers @@ -463,7 +473,8 @@ async def add_multiple( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Adds multiple tokens to a user and overwrites matching existing tokens. + Registers several device tokens for a user in one call, overwriting any stored + token with a matching value. Args: extra_headers: Send extra headers @@ -503,7 +514,8 @@ async def add_single( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: """ - Adds a single token to a user and overwrites a matching existing token. + Registers one device token for a user against a provider key, overwriting the + token if it already exists. Push sends resolve tokens per user. Args: device: Information about the device the token came from. diff --git a/src/courier/resources/workspace_preferences/topics.py b/src/courier/resources/workspace_preferences/topics.py index 7c2ca936..9ae430b2 100644 --- a/src/courier/resources/workspace_preferences/topics.py +++ b/src/courier/resources/workspace_preferences/topics.py @@ -64,11 +64,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicGetResponse: - """Create a subscription preference topic inside a workspace preference. + """Creates a subscription topic inside a workspace preference. - Fails with - 404 if the workspace preference does not exist. The topic id is generated and - returned. + The default status + sets whether users start opted in, opted out, or required. Args: default_status: The default subscription status applied when a recipient has not set their own. @@ -128,11 +127,9 @@ def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicGetResponse: - """Retrieve a topic within a workspace preference. - - Returns 404 if the workspace - preference does not exist, the topic does not exist, or the topic belongs to a - different workspace preference. + """ + Returns one subscription topic with its default status, routing options, allowed + preferences, and unsubscribe header setting. Args: extra_headers: Send extra headers @@ -169,7 +166,8 @@ def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicListResponse: """ - List the topics in a workspace preference. + Returns the subscription topics inside a workspace preference, each with its + default status and routing options. Args: extra_headers: Send extra headers @@ -202,10 +200,9 @@ def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive a topic and remove it from its workspace preference. - - Same 404 rules as - GET. + """ + Archives a subscription topic and removes it from its workspace preference, + addressed by section id and topic id. Args: extra_headers: Send extra headers @@ -344,11 +341,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicGetResponse: - """Create a subscription preference topic inside a workspace preference. + """Creates a subscription topic inside a workspace preference. - Fails with - 404 if the workspace preference does not exist. The topic id is generated and - returned. + The default status + sets whether users start opted in, opted out, or required. Args: default_status: The default subscription status applied when a recipient has not set their own. @@ -408,11 +404,9 @@ async def retrieve( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicGetResponse: - """Retrieve a topic within a workspace preference. - - Returns 404 if the workspace - preference does not exist, the topic does not exist, or the topic belongs to a - different workspace preference. + """ + Returns one subscription topic with its default status, routing options, allowed + preferences, and unsubscribe header setting. Args: extra_headers: Send extra headers @@ -449,7 +443,8 @@ async def list( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceTopicListResponse: """ - List the topics in a workspace preference. + Returns the subscription topics inside a workspace preference, each with its + default status and routing options. Args: extra_headers: Send extra headers @@ -482,10 +477,9 @@ async def archive( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> None: - """Archive a topic and remove it from its workspace preference. - - Same 404 rules as - GET. + """ + Archives a subscription topic and removes it from its workspace preference, + addressed by section id and topic id. Args: extra_headers: Send extra headers diff --git a/src/courier/resources/workspace_preferences/workspace_preferences.py b/src/courier/resources/workspace_preferences/workspace_preferences.py index 361f9551..38339b8f 100644 --- a/src/courier/resources/workspace_preferences/workspace_preferences.py +++ b/src/courier/resources/workspace_preferences/workspace_preferences.py @@ -76,11 +76,10 @@ def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceGetResponse: - """Create a workspace preference. + """Creates a workspace preference and returns its generated id. - The workspace preference id is generated and - returned. Topics are created inside a workspace preference via POST - /preferences/sections/{section_id}/topics. + Add subscription + topics to it afterwards with the topics endpoint. Args: name: Human-readable name for the workspace preference. @@ -128,7 +127,8 @@ def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceGetResponse: """ - Retrieve a workspace preference by id, including its topics. + Returns one workspace preference by id, including its subscription topics, + routing options, and custom routing flag. Args: extra_headers: Send extra headers @@ -159,10 +159,9 @@ def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceListResponse: - """List the workspace's preferences. - - Each workspace preference embeds its topics. - Scoped to the workspace of the API key. + """ + Returns the workspace's preferences, each embedding its subscription topics, + routing options, and whether custom routing is allowed. """ return self._get( "/preferences/sections", @@ -221,11 +220,9 @@ def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PublishPreferencesResponse: - """Publish the workspace's preferences page. - - Takes a snapshot of every workspace - preference with its topics under a new published version, making the current - state visible on the hosted preferences page (non-draft). + """ + Publishes the workspace preference page, snapshotting every preference and + topic, and returns the page id and a preview URL. Args: brand_id: Brand for the hosted page - "default" (workspace default brand), "none" (no @@ -355,11 +352,10 @@ async def create( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceGetResponse: - """Create a workspace preference. + """Creates a workspace preference and returns its generated id. - The workspace preference id is generated and - returned. Topics are created inside a workspace preference via POST - /preferences/sections/{section_id}/topics. + Add subscription + topics to it afterwards with the topics endpoint. Args: name: Human-readable name for the workspace preference. @@ -407,7 +403,8 @@ async def retrieve( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceGetResponse: """ - Retrieve a workspace preference by id, including its topics. + Returns one workspace preference by id, including its subscription topics, + routing options, and custom routing flag. Args: extra_headers: Send extra headers @@ -438,10 +435,9 @@ async def list( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> WorkspacePreferenceListResponse: - """List the workspace's preferences. - - Each workspace preference embeds its topics. - Scoped to the workspace of the API key. + """ + Returns the workspace's preferences, each embedding its subscription topics, + routing options, and whether custom routing is allowed. """ return await self._get( "/preferences/sections", @@ -500,11 +496,9 @@ async def publish( extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> PublishPreferencesResponse: - """Publish the workspace's preferences page. - - Takes a snapshot of every workspace - preference with its topics under a new published version, making the current - state visible on the hosted preferences page (non-draft). + """ + Publishes the workspace preference page, snapshotting every preference and + topic, and returns the page id and a preview URL. Args: brand_id: Brand for the hosted page - "default" (workspace default brand), "none" (no From fd67880214b14693f46b65c9af39dad95f4f7819 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 00:05:53 +0000 Subject: [PATCH 3/3] release: 7.21.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 9 +++++++++ pyproject.toml | 2 +- src/courier/_version.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8696062a..e2691609 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "7.21.0" + ".": "7.21.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 55b22b49..ff3d7c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 7.21.1 (2026-07-25) + +Full Changelog: [v7.21.0...v7.21.1](https://github.com/trycourier/courier-python/compare/v7.21.0...v7.21.1) + +### Documentation + +* **openapi:** describe user topic-preference fields explicitly ([#172](https://github.com/trycourier/courier-python/issues/172)) ([842699a](https://github.com/trycourier/courier-python/commit/842699a68811d63aca9ef8d8865266623ff3e42c)) +* **openapi:** rewrite operation descriptions for agents and SEO ([#174](https://github.com/trycourier/courier-python/issues/174)) ([c90b5d3](https://github.com/trycourier/courier-python/commit/c90b5d325da4e542a46a089084205ce145d65ef1)) + ## 7.21.0 (2026-07-23) Full Changelog: [v7.20.0...v7.21.0](https://github.com/trycourier/courier-python/compare/v7.20.0...v7.21.0) diff --git a/pyproject.toml b/pyproject.toml index caddccb4..276e5666 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "trycourier" -version = "7.21.0" +version = "7.21.1" description = "The official Python library for the Courier API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/courier/_version.py b/src/courier/_version.py index 04464d32..2634e077 100644 --- a/src/courier/_version.py +++ b/src/courier/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "courier" -__version__ = "7.21.0" # x-release-please-version +__version__ = "7.21.1" # x-release-please-version