diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 6d9e5fc..2c543c4 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
 {
-  ".": "1.20.0"
+  ".": "1.21.0"
 }
diff --git a/.stats.yml b/.stats.yml
index e0c39b9..7fd34dc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
 configured_endpoints: 89
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-fe051300804a0ee8b0212b288cec99c00918e570f4c4b8852f3f4a27afdddd1c.yml
-openapi_spec_hash: d2f75f52ceb88b56e4fcf58bf876fe44
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-40ca41599f579fdd44c2e3e32a7d1bba51ba567050c0dcd5bc099ce8d48bba97.yml
+openapi_spec_hash: 72e32d434bbd7ccf7296a2eed7c642ef
 config_hash: 658c551418df454aa40794f8ac679c18
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7b15ee..79b03a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
 # Changelog
 
+## 1.21.0 (2025-10-24)
+
+Full Changelog: [v1.20.0...v1.21.0](https://github.com/knocklabs/knock-node/compare/v1.20.0...v1.21.0)
+
+### Features
+
+* **api:** api update ([84663aa](https://github.com/knocklabs/knock-node/commit/84663aa656c831dd682d3be8386420ad536572d4))
+* **api:** api update ([e768187](https://github.com/knocklabs/knock-node/commit/e768187a2295fb584967d884d3c61b2893ab33bc))
+* **api:** api update ([d100fa3](https://github.com/knocklabs/knock-node/commit/d100fa3559c73438ca544e113c79114f71ab6901))
+* **api:** api update ([90cb9fd](https://github.com/knocklabs/knock-node/commit/90cb9fdd7810f58821c75911469fd2d871361820))
+* **api:** api update ([9187675](https://github.com/knocklabs/knock-node/commit/9187675bf84ca91b29a2d33bd5d27caa88c61307))
+* **api:** api update ([4bb96bc](https://github.com/knocklabs/knock-node/commit/4bb96bc2ff6b8bd9bb2a5cd001fd760d2552c2e6))
+
 ## 1.20.0 (2025-10-07)
 
 Full Changelog: [v1.19.0...v1.20.0](https://github.com/knocklabs/knock-node/compare/v1.19.0...v1.20.0)
diff --git a/api.md b/api.md
index c982d5b..8c40f62 100644
--- a/api.md
+++ b/api.md
@@ -38,8 +38,6 @@ Types:
 - DiscordChannelData
 - InlineChannelDataRequest
 - MsTeamsChannelData
-- OneSignalChannelData
-- PushChannelData
 - SlackChannelData
 
 # Users
diff --git a/package.json b/package.json
index 1b4de83..1a30951 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@knocklabs/node",
-  "version": "1.20.0",
+  "version": "1.21.0",
   "description": "The official TypeScript library for the Knock API",
   "author": "Knock ",
   "types": "dist/index.d.ts",
diff --git a/src/resources/messages/messages.ts b/src/resources/messages/messages.ts
index 62e5d99..91ef1fa 100644
--- a/src/resources/messages/messages.ts
+++ b/src/resources/messages/messages.ts
@@ -334,7 +334,7 @@ export interface Message {
   __typename: string;
 
   /**
-   * The ID for the channel the message was sent through.
+   * @deprecated Deprecated, use channel.id instead.
    */
   channel_id: string;
 
@@ -381,6 +381,11 @@ export interface Message {
    */
   archived_at?: string | null;
 
+  /**
+   * A configured channel, which is a way to route messages to a provider.
+   */
+  channel?: Message.Channel;
+
   /**
    * Timestamp when the message was clicked.
    */
@@ -469,6 +474,46 @@ export namespace Message {
      */
     type?: 'broadcast' | 'workflow' | 'guide';
   }
+
+  /**
+   * A configured channel, which is a way to route messages to a provider.
+   */
+  export interface Channel {
+    /**
+     * The unique identifier for the channel.
+     */
+    id: string;
+
+    /**
+     * The timestamp of when the channel was created.
+     */
+    created_at: string;
+
+    /**
+     * The ID of the provider that this channel uses to deliver messages.
+     */
+    provider: string;
+
+    /**
+     * The type of channel, determining what kind of messages it can send.
+     */
+    type: 'email' | 'in_app' | 'in_app_feed' | 'in_app_guide' | 'sms' | 'push' | 'chat' | 'http';
+
+    /**
+     * The timestamp of when the channel was last updated.
+     */
+    updated_at: string;
+
+    /**
+     * Unique identifier for the channel within a project (immutable once created).
+     */
+    key?: string | null;
+
+    /**
+     * The human-readable name of the channel.
+     */
+    name?: string | null;
+  }
 }
 
 /**
diff --git a/src/resources/objects/objects.ts b/src/resources/objects/objects.ts
index d89622c..8097cb5 100644
--- a/src/resources/objects/objects.ts
+++ b/src/resources/objects/objects.ts
@@ -365,13 +365,16 @@ export class Objects extends APIResource {
    *     __persistence_strategy__: 'merge',
    *     categories: {
    *       marketing: false,
-   *       transactional: { channel_types: { email: false } },
+   *       transactional: { ... },
    *     },
    *     channel_types: { email: true },
+   *     channels: {
+   *       '2f641633-95d3-4555-9222-9f1eb7888a80': { ... },
+   *       'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+   *     },
+   *     commercial_subscribed: true,
    *     workflows: {
-   *       'dinosaurs-loose': {
-   *         channel_types: { email: false },
-   *       },
+   *       'dinosaurs-loose': { ... },
    *     },
    *   },
    * );
@@ -703,25 +706,45 @@ export interface ObjectSetChannelDataParams {
    * Channel data for a given channel type.
    */
   data:
-    | ChannelDataAPI.PushChannelData
-    | ChannelDataAPI.OneSignalChannelData
-    | ObjectSetChannelDataParams.AwsSnsPushChannelData
+    | ObjectSetChannelDataParams.PushChannelDataTokensOnly
+    | ObjectSetChannelDataParams.AwssnsPushChannelDataTargetArNsOnly
+    | ObjectSetChannelDataParams.OneSignalChannelDataPlayerIDsOnly
     | ChannelDataAPI.SlackChannelData
     | ChannelDataAPI.MsTeamsChannelData
     | ChannelDataAPI.DiscordChannelData;
 }
 
 export namespace ObjectSetChannelDataParams {
+  /**
+   * Push channel data.
+   */
+  export interface PushChannelDataTokensOnly {
+    /**
+     * A list of push channel tokens.
+     */
+    tokens: Array;
+  }
+
   /**
    * AWS SNS push channel data.
    */
-  export interface AwsSnsPushChannelData {
+  export interface AwssnsPushChannelDataTargetArNsOnly {
     /**
      * A list of platform endpoint ARNs. See
      * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
      */
     target_arns: Array;
   }
+
+  /**
+   * OneSignal channel data.
+   */
+  export interface OneSignalChannelDataPlayerIDsOnly {
+    /**
+     * A list of OneSignal player IDs.
+     */
+    player_ids: Array;
+  }
 }
 
 export interface ObjectSetPreferencesParams {
@@ -744,6 +767,17 @@ export interface ObjectSetPreferencesParams {
    */
   channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+  /**
+   * Channel preferences.
+   */
+  channels?: { [key: string]: boolean | ObjectSetPreferencesParams.PreferenceSetChannelSetting } | null;
+
+  /**
+   * Whether the recipient is subscribed to commercial communications. When false,
+   * the recipient will not receive commercial workflow notifications.
+   */
+  commercial_subscribed?: boolean | null;
+
   /**
    * An object where the key is the workflow key and the values are the preference
    * settings for that workflow.
@@ -764,12 +798,43 @@ export namespace ObjectSetPreferencesParams {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
 
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
+
+  /**
+   * A set of settings for a specific channel. Currently, this can only be a list of
+   * conditions to apply.
+   */
+  export interface PreferenceSetChannelSetting {
+    /**
+     * A list of conditions to apply to a specific channel.
+     */
+    conditions: Array;
+  }
+
   /**
    * The settings object for a workflow or category, where you can specify channel
    * types or conditions.
@@ -780,11 +845,31 @@ export namespace ObjectSetPreferencesParams {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
+
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
 }
 
 Objects.Bulk = Bulk;
diff --git a/src/resources/recipients/channel-data.ts b/src/resources/recipients/channel-data.ts
index 3675055..b0c6e1f 100644
--- a/src/resources/recipients/channel-data.ts
+++ b/src/resources/recipients/channel-data.ts
@@ -22,12 +22,12 @@ export interface ChannelData {
    * Channel data for a given channel type.
    */
   data:
-    | PushChannelData
+    | ChannelData.PushChannelDataFull
+    | ChannelData.AwssnsPushChannelDataFull
+    | ChannelData.OneSignalChannelDataPlayerIDsOnly
     | SlackChannelData
     | MsTeamsChannelData
-    | DiscordChannelData
-    | OneSignalChannelData
-    | ChannelData.AwsSnsPushChannelData;
+    | DiscordChannelData;
 
   /**
    * The type of provider.
@@ -45,16 +45,96 @@ export interface ChannelData {
 }
 
 export namespace ChannelData {
+  /**
+   * Push channel data.
+   */
+  export interface PushChannelDataFull {
+    /**
+     * A list of devices. Each device contains a token, and optionally a locale and
+     * timezone.
+     */
+    devices: Array;
+
+    /**
+     * A list of push channel tokens.
+     */
+    tokens: Array;
+  }
+
+  export namespace PushChannelDataFull {
+    export interface Device {
+      /**
+       * The device token to send the push notification to.
+       */
+      token: string;
+
+      /**
+       * The locale of the object. Used for
+       * [message localization](/concepts/translations).
+       */
+      locale?: string | null;
+
+      /**
+       * The timezone of the object. Must be a
+       * valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+       * Used
+       * for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients).
+       */
+      timezone?: string | null;
+    }
+  }
+
   /**
    * AWS SNS push channel data.
    */
-  export interface AwsSnsPushChannelData {
+  export interface AwssnsPushChannelDataFull {
+    /**
+     * A list of devices. Each device contains a target_arn, and optionally a locale
+     * and timezone.
+     */
+    devices: Array;
+
     /**
      * A list of platform endpoint ARNs. See
      * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
      */
     target_arns: Array;
   }
+
+  export namespace AwssnsPushChannelDataFull {
+    export interface Device {
+      /**
+       * The ARN of a platform endpoint associated with a platform application and a
+       * device token. See
+       * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
+       */
+      target_arn: string;
+
+      /**
+       * The locale of the object. Used for
+       * [message localization](/concepts/translations).
+       */
+      locale?: string | null;
+
+      /**
+       * The timezone of the object. Must be a
+       * valid [tz database time zone string](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+       * Used
+       * for [recurring schedules](/concepts/schedules#scheduling-workflows-with-recurring-schedules-for-recipients).
+       */
+      timezone?: string | null;
+    }
+  }
+
+  /**
+   * OneSignal channel data.
+   */
+  export interface OneSignalChannelDataPlayerIDsOnly {
+    /**
+     * A list of OneSignal player IDs.
+     */
+    player_ids: Array;
+  }
 }
 
 /**
@@ -65,25 +145,45 @@ export interface ChannelDataRequest {
    * Channel data for a given channel type.
    */
   data:
-    | PushChannelData
-    | OneSignalChannelData
-    | ChannelDataRequest.AwsSnsPushChannelData
+    | ChannelDataRequest.PushChannelDataTokensOnly
+    | ChannelDataRequest.AwssnsPushChannelDataTargetArNsOnly
+    | ChannelDataRequest.OneSignalChannelDataPlayerIDsOnly
     | SlackChannelData
     | MsTeamsChannelData
     | DiscordChannelData;
 }
 
 export namespace ChannelDataRequest {
+  /**
+   * Push channel data.
+   */
+  export interface PushChannelDataTokensOnly {
+    /**
+     * A list of push channel tokens.
+     */
+    tokens: Array;
+  }
+
   /**
    * AWS SNS push channel data.
    */
-  export interface AwsSnsPushChannelData {
+  export interface AwssnsPushChannelDataTargetArNsOnly {
     /**
      * A list of platform endpoint ARNs. See
      * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
      */
     target_arns: Array;
   }
+
+  /**
+   * OneSignal channel data.
+   */
+  export interface OneSignalChannelDataPlayerIDsOnly {
+    /**
+     * A list of OneSignal player IDs.
+     */
+    player_ids: Array;
+  }
 }
 
 /**
@@ -137,25 +237,45 @@ export namespace DiscordChannelData {
  */
 export type InlineChannelDataRequest = {
   [key: string]:
-    | PushChannelData
-    | OneSignalChannelData
-    | InlineChannelDataRequest.AwsSnsPushChannelData
+    | InlineChannelDataRequest.PushChannelDataTokensOnly
+    | InlineChannelDataRequest.AwssnsPushChannelDataTargetArNsOnly
+    | InlineChannelDataRequest.OneSignalChannelDataPlayerIDsOnly
     | SlackChannelData
     | MsTeamsChannelData
     | DiscordChannelData;
 };
 
 export namespace InlineChannelDataRequest {
+  /**
+   * Push channel data.
+   */
+  export interface PushChannelDataTokensOnly {
+    /**
+     * A list of push channel tokens.
+     */
+    tokens: Array;
+  }
+
   /**
    * AWS SNS push channel data.
    */
-  export interface AwsSnsPushChannelData {
+  export interface AwssnsPushChannelDataTargetArNsOnly {
     /**
      * A list of platform endpoint ARNs. See
      * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
      */
     target_arns: Array;
   }
+
+  /**
+   * OneSignal channel data.
+   */
+  export interface OneSignalChannelDataPlayerIDsOnly {
+    /**
+     * A list of OneSignal player IDs.
+     */
+    player_ids: Array;
+  }
 }
 
 /**
@@ -224,26 +344,6 @@ export namespace MsTeamsChannelData {
   }
 }
 
-/**
- * OneSignal channel data.
- */
-export interface OneSignalChannelData {
-  /**
-   * A list of OneSignal player IDs.
-   */
-  player_ids: Array;
-}
-
-/**
- * Push channel data.
- */
-export interface PushChannelData {
-  /**
-   * A list of push channel tokens.
-   */
-  tokens: Array;
-}
-
 /**
  * Slack channel data.
  */
@@ -308,8 +408,6 @@ export declare namespace ChannelData {
     type DiscordChannelData as DiscordChannelData,
     type InlineChannelDataRequest as InlineChannelDataRequest,
     type MsTeamsChannelData as MsTeamsChannelData,
-    type OneSignalChannelData as OneSignalChannelData,
-    type PushChannelData as PushChannelData,
     type SlackChannelData as SlackChannelData,
   };
 }
diff --git a/src/resources/recipients/index.ts b/src/resources/recipients/index.ts
index b63510e..161df76 100644
--- a/src/resources/recipients/index.ts
+++ b/src/resources/recipients/index.ts
@@ -6,8 +6,6 @@ export {
   type DiscordChannelData,
   type InlineChannelDataRequest,
   type MsTeamsChannelData,
-  type OneSignalChannelData,
-  type PushChannelData,
   type SlackChannelData,
 } from './channel-data';
 export {
diff --git a/src/resources/recipients/preferences.ts b/src/resources/recipients/preferences.ts
index 5ee5ddd..69c7b53 100644
--- a/src/resources/recipients/preferences.ts
+++ b/src/resources/recipients/preferences.ts
@@ -34,6 +34,17 @@ export interface PreferenceSet {
    */
   channel_types?: PreferenceSetChannelTypes | null;
 
+  /**
+   * Channel preferences.
+   */
+  channels?: { [key: string]: boolean | PreferenceSet.PreferenceSetChannelSetting } | null;
+
+  /**
+   * Whether the recipient is subscribed to commercial communications. When false,
+   * the recipient will not receive commercial workflow notifications.
+   */
+  commercial_subscribed?: boolean | null;
+
   /**
    * An object where the key is the workflow key and the values are the preference
    * settings for that workflow.
@@ -52,12 +63,43 @@ export namespace PreferenceSet {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
 
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
+
+  /**
+   * A set of settings for a specific channel. Currently, this can only be a list of
+   * conditions to apply.
+   */
+  export interface PreferenceSetChannelSetting {
+    /**
+     * A list of conditions to apply to a specific channel.
+     */
+    conditions: Array;
+  }
+
   /**
    * The settings object for a workflow or category, where you can specify channel
    * types or conditions.
@@ -68,11 +110,31 @@ export namespace PreferenceSet {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
+
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
 }
 
 /**
@@ -144,6 +206,17 @@ export interface PreferenceSetRequest {
    */
   channel_types?: PreferenceSetChannelTypes | null;
 
+  /**
+   * Channel preferences.
+   */
+  channels?: { [key: string]: boolean | PreferenceSetRequest.PreferenceSetChannelSetting } | null;
+
+  /**
+   * Whether the recipient is subscribed to commercial communications. When false,
+   * the recipient will not receive commercial workflow notifications.
+   */
+  commercial_subscribed?: boolean | null;
+
   /**
    * An object where the key is the workflow key and the values are the preference
    * settings for that workflow.
@@ -164,12 +237,43 @@ export namespace PreferenceSetRequest {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
 
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
+
+  /**
+   * A set of settings for a specific channel. Currently, this can only be a list of
+   * conditions to apply.
+   */
+  export interface PreferenceSetChannelSetting {
+    /**
+     * A list of conditions to apply to a specific channel.
+     */
+    conditions: Array;
+  }
+
   /**
    * The settings object for a workflow or category, where you can specify channel
    * types or conditions.
@@ -180,11 +284,31 @@ export namespace PreferenceSetRequest {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
+
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
 }
 
 export declare namespace Preferences {
diff --git a/src/resources/recipients/recipients.ts b/src/resources/recipients/recipients.ts
index 387feb0..861faae 100644
--- a/src/resources/recipients/recipients.ts
+++ b/src/resources/recipients/recipients.ts
@@ -9,8 +9,6 @@ import {
   DiscordChannelData,
   InlineChannelDataRequest,
   MsTeamsChannelData,
-  OneSignalChannelData,
-  PushChannelData,
   SlackChannelData,
 } from './channel-data';
 import * as PreferencesAPI from './preferences';
@@ -94,8 +92,6 @@ export declare namespace Recipients {
     type DiscordChannelData as DiscordChannelData,
     type InlineChannelDataRequest as InlineChannelDataRequest,
     type MsTeamsChannelData as MsTeamsChannelData,
-    type OneSignalChannelData as OneSignalChannelData,
-    type PushChannelData as PushChannelData,
     type SlackChannelData as SlackChannelData,
   };
 }
diff --git a/src/resources/users/bulk.ts b/src/resources/users/bulk.ts
index d9fd2ba..c7e311f 100644
--- a/src/resources/users/bulk.ts
+++ b/src/resources/users/bulk.ts
@@ -63,6 +63,19 @@ export class Bulk extends APIResource {
    *         transactional: { channel_types: { email: false } },
    *       },
    *       channel_types: { email: true },
+   *       channels: {
+   *         '2f641633-95d3-4555-9222-9f1eb7888a80': {
+   *           conditions: [
+   *             {
+   *               argument: 'US',
+   *               operator: 'equal_to',
+   *               variable: 'recipient.country_code',
+   *             },
+   *           ],
+   *         },
+   *         'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+   *       },
+   *       commercial_subscribed: true,
    *       workflows: {
    *         'dinosaurs-loose': {
    *           channel_types: { email: false },
diff --git a/src/resources/users/guides.ts b/src/resources/users/guides.ts
index db18001..79d7d20 100644
--- a/src/resources/users/guides.ts
+++ b/src/resources/users/guides.ts
@@ -142,50 +142,149 @@ export interface GuideGetChannelResponse {
   /**
    * A list of guides.
    */
-  guides: Array;
+  entries: Array;
 
   /**
-   * The recipient of the guide.
+   * A map of guide group keys to their last display timestamps.
    */
-  recipient?: GuideGetChannelResponse.Recipient | null;
+  guide_group_display_logs: { [key: string]: string };
+
+  /**
+   * A list of guide groups with their display sequences and intervals.
+   */
+  guide_groups: Array;
 }
 
 export namespace GuideGetChannelResponse {
-  export interface Guide {
+  export interface Entry {
     /**
      * The unique identifier for the guide.
      */
     id?: string;
 
     /**
-     * Whether the guide is active.
+     * The typename of the schema.
      */
-    active?: boolean;
+    __typename?: string;
 
     /**
-     * The content of the guide.
+     * A list of URL Patterns to evaluate user's current location to activate the
+     * guide, if matched
      */
-    content?: string;
+    activation_url_patterns?: Array;
 
     /**
-     * The metadata of the guide.
+     * A list of URL rules to evaluate user's current location to activate the guide,
+     * if matched
      */
-    metadata?: { [key: string]: unknown };
+    activation_url_rules?: Array;
 
     /**
-     * The title of the guide.
+     * Whether the guide is active.
      */
-    title?: string;
-  }
+    active?: boolean;
+
+    bypass_global_group_limit?: boolean;
+
+    channel_id?: string;
+
+    inserted_at?: string;
 
-  /**
-   * The recipient of the guide.
-   */
-  export interface Recipient {
     /**
-     * Unique identifier for the recipient.
+     * The key of the guide.
      */
-    id?: string;
+    key?: string;
+
+    semver?: string;
+
+    steps?: Array;
+
+    /**
+     * The type of the guide.
+     */
+    type?: string;
+
+    updated_at?: string;
+  }
+
+  export namespace Entry {
+    export interface ActivationURLPattern {
+      /**
+       * The directive for the URL pattern ('allow' or 'block')
+       */
+      directive?: string;
+
+      /**
+       * The pathname pattern to match (supports wildcards like /\*)
+       */
+      pathname?: string;
+    }
+
+    export interface ActivationURLRule {
+      /**
+       * The value to compare against
+       */
+      argument?: string;
+
+      /**
+       * The directive for the URL pattern ('allow' or 'block')
+       */
+      directive?: string;
+
+      /**
+       * The comparison operator ('contains' or 'equal_to')
+       */
+      operator?: string;
+
+      /**
+       * The variable to evaluate ('pathname')
+       */
+      variable?: string;
+    }
+
+    export interface Step {
+      content?: { [key: string]: unknown };
+
+      message?: Step.Message;
+
+      ref?: string;
+
+      schema_key?: string;
+
+      schema_semver?: string;
+
+      schema_variant_key?: string;
+    }
+
+    export namespace Step {
+      export interface Message {
+        id?: string | null;
+
+        archived_at?: string | null;
+
+        interacted_at?: string | null;
+
+        link_clicked_at?: string | null;
+
+        read_at?: string | null;
+
+        seen_at?: string | null;
+      }
+    }
+  }
+
+  export interface GuideGroup {
+    __typename?: string;
+
+    display_interval?: number;
+
+    display_sequence?: Array;
+
+    inserted_at?: string;
+
+    key?: string;
+
+    updated_at?: string;
   }
 }
 
diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts
index c98f726..ae7118c 100644
--- a/src/resources/users/users.ts
+++ b/src/resources/users/users.ts
@@ -316,6 +316,19 @@ export class Users extends APIResource {
    *       transactional: { channel_types: { email: false } },
    *     },
    *     channel_types: { email: true },
+   *     channels: {
+   *       '2f641633-95d3-4555-9222-9f1eb7888a80': {
+   *         conditions: [
+   *           {
+   *             argument: 'US',
+   *             operator: 'equal_to',
+   *             variable: 'recipient.country_code',
+   *           },
+   *         ],
+   *       },
+   *       'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+   *     },
+   *     commercial_subscribed: true,
    *     workflows: {
    *       'dinosaurs-loose': {
    *         channel_types: { email: false },
@@ -735,25 +748,45 @@ export interface UserSetChannelDataParams {
    * Channel data for a given channel type.
    */
   data:
-    | ChannelDataAPI.PushChannelData
-    | ChannelDataAPI.OneSignalChannelData
-    | UserSetChannelDataParams.AwsSnsPushChannelData
+    | UserSetChannelDataParams.PushChannelDataTokensOnly
+    | UserSetChannelDataParams.AwssnsPushChannelDataTargetArNsOnly
+    | UserSetChannelDataParams.OneSignalChannelDataPlayerIDsOnly
     | ChannelDataAPI.SlackChannelData
     | ChannelDataAPI.MsTeamsChannelData
     | ChannelDataAPI.DiscordChannelData;
 }
 
 export namespace UserSetChannelDataParams {
+  /**
+   * Push channel data.
+   */
+  export interface PushChannelDataTokensOnly {
+    /**
+     * A list of push channel tokens.
+     */
+    tokens: Array;
+  }
+
   /**
    * AWS SNS push channel data.
    */
-  export interface AwsSnsPushChannelData {
+  export interface AwssnsPushChannelDataTargetArNsOnly {
     /**
      * A list of platform endpoint ARNs. See
      * [Setting up an Amazon SNS platform endpoint for mobile notifications](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).
      */
     target_arns: Array;
   }
+
+  /**
+   * OneSignal channel data.
+   */
+  export interface OneSignalChannelDataPlayerIDsOnly {
+    /**
+     * A list of OneSignal player IDs.
+     */
+    player_ids: Array;
+  }
 }
 
 export interface UserSetPreferencesParams {
@@ -776,6 +809,17 @@ export interface UserSetPreferencesParams {
    */
   channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+  /**
+   * Channel preferences.
+   */
+  channels?: { [key: string]: boolean | UserSetPreferencesParams.PreferenceSetChannelSetting } | null;
+
+  /**
+   * Whether the recipient is subscribed to commercial communications. When false,
+   * the recipient will not receive commercial workflow notifications.
+   */
+  commercial_subscribed?: boolean | null;
+
   /**
    * An object where the key is the workflow key and the values are the preference
    * settings for that workflow.
@@ -796,12 +840,43 @@ export namespace UserSetPreferencesParams {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
 
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
+
+  /**
+   * A set of settings for a specific channel. Currently, this can only be a list of
+   * conditions to apply.
+   */
+  export interface PreferenceSetChannelSetting {
+    /**
+     * A list of conditions to apply to a specific channel.
+     */
+    conditions: Array;
+  }
+
   /**
    * The settings object for a workflow or category, where you can specify channel
    * types or conditions.
@@ -812,11 +887,31 @@ export namespace UserSetPreferencesParams {
      */
     channel_types?: PreferencesAPI.PreferenceSetChannelTypes | null;
 
+    /**
+     * Channel preferences.
+     */
+    channels?: {
+      [key: string]: boolean | PreferenceSetWorkflowCategorySettingObject.PreferenceSetChannelSetting;
+    } | null;
+
     /**
      * A list of conditions to apply to a channel type.
      */
     conditions?: Array | null;
   }
+
+  export namespace PreferenceSetWorkflowCategorySettingObject {
+    /**
+     * A set of settings for a specific channel. Currently, this can only be a list of
+     * conditions to apply.
+     */
+    export interface PreferenceSetChannelSetting {
+      /**
+       * A list of conditions to apply to a specific channel.
+       */
+      conditions: Array;
+    }
+  }
 }
 
 Users.Feeds = Feeds;
diff --git a/src/version.ts b/src/version.ts
index b28d84d..016fd49 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '1.20.0'; // x-release-please-version
+export const VERSION = '1.21.0'; // x-release-please-version
diff --git a/tests/api-resources/objects/bulk.test.ts b/tests/api-resources/objects/bulk.test.ts
index b836d5c..a99f033 100644
--- a/tests/api-resources/objects/bulk.test.ts
+++ b/tests/api-resources/objects/bulk.test.ts
@@ -76,6 +76,7 @@ describe('resource bulk', () => {
                           ],
                         },
                       },
+                      channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                       conditions: [
                         { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                       ],
@@ -93,6 +94,15 @@ describe('resource bulk', () => {
                       ],
                     },
                   },
+                  channels: {
+                    '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                      conditions: [
+                        { argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' },
+                      ],
+                    },
+                    'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+                  },
+                  commercial_subscribed: true,
                   workflows: {
                     'dinosaurs-loose': {
                       channel_types: {
@@ -107,6 +117,7 @@ describe('resource bulk', () => {
                           ],
                         },
                       },
+                      channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                       conditions: [
                         { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                       ],
@@ -160,6 +171,7 @@ describe('resource bulk', () => {
                       ],
                     },
                   },
+                  channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                   conditions: [
                     { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                   ],
@@ -175,6 +187,13 @@ describe('resource bulk', () => {
                   conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
                 },
               },
+              channels: {
+                '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                  conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
+                },
+                'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+              },
+              commercial_subscribed: true,
               workflows: {
                 'dinosaurs-loose': {
                   channel_types: {
@@ -189,6 +208,7 @@ describe('resource bulk', () => {
                       ],
                     },
                   },
+                  channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                   conditions: [
                     { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                   ],
diff --git a/tests/api-resources/schedules/bulk.test.ts b/tests/api-resources/schedules/bulk.test.ts
index 2fe7e36..82c0bd5 100644
--- a/tests/api-resources/schedules/bulk.test.ts
+++ b/tests/api-resources/schedules/bulk.test.ts
@@ -55,6 +55,7 @@ describe('resource bulk', () => {
                         ],
                       },
                     },
+                    channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                     conditions: [
                       { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                     ],
@@ -72,6 +73,15 @@ describe('resource bulk', () => {
                     ],
                   },
                 },
+                channels: {
+                  '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                    conditions: [
+                      { argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' },
+                    ],
+                  },
+                  'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+                },
+                commercial_subscribed: true,
                 workflows: {
                   'dinosaurs-loose': {
                     channel_types: {
@@ -86,6 +96,7 @@ describe('resource bulk', () => {
                         ],
                       },
                     },
+                    channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                     conditions: [
                       { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                     ],
@@ -141,6 +152,7 @@ describe('resource bulk', () => {
                         ],
                       },
                     },
+                    channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                     conditions: [
                       { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                     ],
@@ -158,6 +170,15 @@ describe('resource bulk', () => {
                     ],
                   },
                 },
+                channels: {
+                  '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                    conditions: [
+                      { argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' },
+                    ],
+                  },
+                  'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+                },
+                commercial_subscribed: true,
                 workflows: {
                   'dinosaurs-loose': {
                     channel_types: {
@@ -172,6 +193,7 @@ describe('resource bulk', () => {
                         ],
                       },
                     },
+                    channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                     conditions: [
                       { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                     ],
diff --git a/tests/api-resources/schedules/schedules.test.ts b/tests/api-resources/schedules/schedules.test.ts
index ce002c8..cb04e80 100644
--- a/tests/api-resources/schedules/schedules.test.ts
+++ b/tests/api-resources/schedules/schedules.test.ts
@@ -55,6 +55,7 @@ describe('resource schedules', () => {
                     ],
                   },
                 },
+                channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                 conditions: [
                   { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                 ],
@@ -70,6 +71,13 @@ describe('resource schedules', () => {
                 conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
               },
             },
+            channels: {
+              '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
+              },
+              'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+            },
+            commercial_subscribed: true,
             workflows: {
               'dinosaurs-loose': {
                 channel_types: {
@@ -84,6 +92,7 @@ describe('resource schedules', () => {
                     ],
                   },
                 },
+                channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                 conditions: [
                   { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                 ],
diff --git a/tests/api-resources/users/bulk.test.ts b/tests/api-resources/users/bulk.test.ts
index 3d84ecf..82ded10 100644
--- a/tests/api-resources/users/bulk.test.ts
+++ b/tests/api-resources/users/bulk.test.ts
@@ -68,6 +68,7 @@ describe('resource bulk', () => {
                       ],
                     },
                   },
+                  channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                   conditions: [
                     { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                   ],
@@ -83,6 +84,13 @@ describe('resource bulk', () => {
                   conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
                 },
               },
+              channels: {
+                '2f641633-95d3-4555-9222-9f1eb7888a80': {
+                  conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
+                },
+                'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+              },
+              commercial_subscribed: true,
               workflows: {
                 'dinosaurs-loose': {
                   channel_types: {
@@ -97,6 +105,7 @@ describe('resource bulk', () => {
                       ],
                     },
                   },
+                  channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
                   conditions: [
                     { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
                   ],
@@ -143,6 +152,7 @@ describe('resource bulk', () => {
                 conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
               },
             },
+            channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
             conditions: [
               { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
             ],
@@ -156,6 +166,13 @@ describe('resource bulk', () => {
           push: true,
           sms: { conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }] },
         },
+        channels: {
+          '2f641633-95d3-4555-9222-9f1eb7888a80': {
+            conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
+          },
+          'aef6e715-df82-4ab6-b61e-b743e249f7b6': true,
+        },
+        commercial_subscribed: true,
         workflows: {
           'dinosaurs-loose': {
             channel_types: {
@@ -168,6 +185,7 @@ describe('resource bulk', () => {
                 conditions: [{ argument: 'US', operator: 'equal_to', variable: 'recipient.country_code' }],
               },
             },
+            channels: { 'aef6e715-df82-4ab6-b61e-b743e249f7b6': true },
             conditions: [
               { argument: 'frog_genome', operator: 'contains', variable: 'specimen.dna_sequence' },
             ],