# Push preferences

Users control which notifications they receive with push preferences, set through the same `setPushPreferences` endpoint across products. Preferences use a per-product level field: `chat_level` and `call_level` for Chat and Video, `feeds_level` for Activity Feeds. All of them support temporarily disabling push until a timestamp with `disabled_until`.

## Chat and Video Push Preferences

Push preferences allow users to control how they receive push notifications. You can set preferences at the user level (global preferences), the channel-member level (per-channel preferences), and the channel configuration level (on channel types or channel config overrides). At the user and channel-member level, preferences use `chat_level`; at the channel configuration level, the equivalent field is `push_level`. Both accept the same values. Alternatively, you can use [granular per-category toggles](#granular-chat-preferences) (`chat_preferences`) for independent control over each mention type.

### How Push Preferences Work

<Admonition type="warning">

Users must be channel members to receive push notifications regardless of their preferences.

</Admonition>

#### Chat push preferences operate on three levels

- **Channel-member preferences**: Per-channel preferences set by (or for) a specific user. These take the highest priority.
- **User-level preferences**: Global preferences that apply to all channels for a user, used when no channel-member preference exists.
- **Channel configuration `push_level`**: Set on the channel type or as a channel config override. Acts as the default for all members of that channel when no user-level or channel-member preference exists.

#### Chat push preferences support four levels of notifications

- **all**: Receive push notifications for every message **(default)**.
- **all_mentions**: Receive push notifications when mentioned by any mention type — direct user mentions, `@here`, `@channel`, role mentions, and group mentions.
- **direct_mentions**: Receive push notifications only for direct user mentions (`mentioned_users`). Indirect mentions like `@here`, `@channel`, role mentions, and group mentions do not trigger a push.
- **none**: Do not receive push notifications.

The legacy value `mentions` is treated as `direct_mentions` for backward compatibility.

For more fine-grained control, you can use [granular chat preferences](#granular-chat-preferences) instead of these levels, allowing you to toggle each mention type independently.

Additionally, you can temporarily disable push notifications until a specific time using the `disabled_until` parameter.

#### The system evaluates preferences in the following priority order

1. **Channel-member preferences** are checked first (if they exist for the user on the specific channel).
2. If no channel-member preference exists, **user-level (global) preferences** are used.
3. If no user-level preference exists, the **channel configuration `push_level`** is used (set on the channel type or as a channel config override).
4. If no preferences are set at any level, the default behavior is `all`.
5. **Temporary disabling**: If `disabled_until` is set and the current time is before that timestamp, notifications are disabled regardless of other preferences.

### Setting Push Preferences

#### User-Level Preferences

Set global push preferences that apply to all channels for a user:

<Tabs>

```js label="JavaScript"
// Set user-level preferences for multiple users
await client.setPushPreferences([
  {
    user_id: "user-1",
    chat_level: "mentions",
  },
  {
    user_id: "user-2",
    chat_level: "all",
  },
  {
    user_id: "user-3",
    chat_level: "none",
  },
]);
```

```kotlin label="Kotlin"
// Set user-level push preferences for the current user
client.setUserPushPreference(PushPreferenceLevel.mentions).enqueue()
```

```swift label="Swift"
// Set user-level push preferences
let currentUserController = chatClient.currentUserController()
currentUserController.setPushPreference(level: .mentions)
```

</Tabs>

#### Channel-Member Preferences

Set preferences for a specific user on specific channels. These take the highest priority:

<Tabs>

```js label="JavaScript"
// Set channel-level preferences
await client.setPushPreferences([
  {
    user_id: "user-1",
    channel_cid: "messaging:general",
    chat_level: "none",
  },
  {
    user_id: "user-1",
    channel_cid: "messaging:announcements",
    chat_level: "all",
  },
  {
    user_id: "user-2",
    channel_cid: "messaging:general",
    chat_level: "mentions",
  },
]);
```

```kotlin label="Kotlin"
// Set per-channel preferences for the current user
client.setChannelPushPreference("messaging:general", PushPreferenceLevel.none).enqueue()
client.setChannelPushPreference("messaging:announcements", PushPreferenceLevel.all).enqueue()
```

```swift label="Swift"
let generalController = chatClient.channelController(
    for: ChannelId(type: .messaging, id: "general")
)
generalController.setPushPreference(level: .none)

let announcementsController = chatClient.channelController(
    for: ChannelId(type: .messaging, id: "announcements")
)
announcementsController.setPushPreference(level: .all)
```

</Tabs>

#### Channel Configuration Push Level

You can set a default `push_level` on a channel type or as a channel config override. This applies to all members of matching channels who have not set their own push preferences.

<Tabs>

```js label="Node.js"
// Set push_level on a channel type
await client.updateChannelType("messaging", {
  push_level: "all_mentions",
});

// Set push_level as a channel config override on a specific channel
const channel = client.channel("messaging", "announcements");
await channel.update({
  config_overrides: {
    push_level: "all",
  },
});
```

```python label="Python"
# Set push_level on a channel type
client.update_channel_type("messaging", push_level="all_mentions")

# Set push_level as a channel config override on a specific channel
channel = client.channel("messaging", "announcements")
channel.update({"config_overrides": {"push_level": "all"}})
```

</Tabs>

<Admonition type="info">

Channel config overrides take precedence over the channel type default. Both accept the same values: `all`, `all_mentions`, `direct_mentions`, and `none`.

</Admonition>

You can also set [granular chat preferences](#granular-chat-preferences) on channel config overrides instead of `push_level`. The two are mutually exclusive — setting one clears the other.

<Tabs>

```js label="JavaScript"
// Set granular chat_preferences as a channel config override
const channel = client.channel("messaging", "announcements");
await channel.update({
  config_overrides: {
    chat_preferences: {
      default_preference: "none",
      channel_mentions: "all",
      direct_mentions: "all",
    },
  },
});
```

```python label="Python"
# Set granular chat_preferences as a channel config override
channel = client.channel("messaging", "announcements")
channel.update({
    "config_overrides": {
        "chat_preferences": {
            "default_preference": "none",
            "channel_mentions": "all",
            "direct_mentions": "all",
        },
    },
})
```

</Tabs>

### Client-Side vs Server-Side Usage

#### Client-Side Usage

When using client-side authentication, users can only update their own push preferences:

<Tabs>

```js label="JavaScript"
// Client-side - can only update current user's preferences
await client.setPushPreferences([
  {
    // user_id is optional and will be automatically set to current user
    chat_level: "mentions",
  },
  {
    // Set preferences for a specific channel
    channel_cid: "messaging:general",
    chat_level: "all",
  },
]);
```

```kotlin label="Kotlin"
// Client-side - can only update current user's preferences
client.setUserPushPreference(PushPreferenceLevel.mentions).enqueue()

// Set preferences for a specific channel
client.setChannelPushPreference("messaging:general", PushPreferenceLevel.all).enqueue()
```

```swift label="Swift"
// Update current user's preferences
let currentUserController = chatClient.currentUserController()
currentUserController.setPushPreference(level: .mentions)

// Set preferences for a specific channel
let channelController = chatClient.channelController(for: ChannelId(type: .messaging, id: "general"))
channelController.setPushPreference(level: .all)
```

</Tabs>

#### Server-Side Usage

Server-side requests can update preferences for any user:

<Tabs>

```js label="Node.js"
// Server-side - can update preferences for any user
await serverClient.setPushPreferences([
  {
    user_id: "user-1",
    chat_level: "mentions",
  },
  {
    user_id: "user-2",
    chat_level: "all",
  },
]);
```

</Tabs>

### Practical Examples

#### 1: Creating a "Do Not Disturb" Mode

<Tabs>

```js label="JavaScript"
// Disable all push notifications
await client.setPushPreferences([
  {
    user_id: "user-id",
    chat_level: "none",
  },
]);

// Later, re-enable all push notifications
await client.setPushPreferences([
  {
    user_id: "user-id",
    chat_level: "all",
  },
]);
```

```kotlin label="Kotlin"
// Disable all push notifications
client.setUserPushPreference(PushPreferenceLevel.none).enqueue()

// Later, re-enable all push notifications
client.setUserPushPreference(PushPreferenceLevel.all).enqueue()
```

```swift label="Swift"
// Disable all push notifications
currentUserController.setPushPreference(level: .none)

// Later, re-enable all push notifications
currentUserController.setPushPreference(level: .all)
```

</Tabs>

#### 2: Channel-Specific Notification Settings

You can set different preferences for each individual channel, allowing users to customize their notification experience on a per-channel basis.

<Tabs>

```js label="JavaScript"
// Set different preferences for different channels
await client.setPushPreferences([
  {
    user_id: "user-id",
    channel_cid: "messaging:general",
    chat_level: "mentions", // Default: mentions only
  },
  {
    user_id: "user-id",
    channel_cid: "messaging:urgent-alerts",
    chat_level: "all", // Always notify for urgent alerts
  },
  {
    user_id: "user-id",
    channel_cid: "messaging:social-chat",
    chat_level: "none", // Never notify for social chat
  },
]);
```

```kotlin label="Kotlin"
// Set different preferences for different channels
// For general channel: mentions only
client.setChannelPushPreference("messaging:general", PushPreferenceLevel.mentions).enqueue()

// For urgent alerts channel: always notify
client.setChannelPushPreference("messaging:urgent-alerts", PushPreferenceLevel.all).enqueue()

// For social chat channel: never notify
client.setChannelPushPreference("messaging:social-chat", PushPreferenceLevel.none).enqueue()
```

```swift label="Swift"
// Set different preferences for different channels
// For general channel: mentions only
generalChannelController.setPushPreference(level: .mentions)

// For urgent alerts channel: always notify
urgentAlertsChannelController.setPushPreference(level: .all)

// For social chat channel: never notify
socialChatChannelController.setPushPreference(level: .none)
```

</Tabs>

#### 3: Temporarily Disabling Push Notifications

You can temporarily disable push notifications until a specific time using the `disabled_until` parameter. This is useful for implementing "Do Not Disturb" periods or scheduled quiet hours.

<Tabs>

```js label="JavaScript"
// Disable push notifications for 2 hours for a specific user
const twoHoursFromNow = new Date(Date.now() + 2 * 60 * 60 * 1000);

await client.setPushPreferences([
  {
    user_id: "user-1",
    chat_level: "all",
    disabled_until: twoHoursFromNow.toISOString(),
  },
]);

// Disable push notifications for a specific channel until tomorrow
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(9, 0, 0, 0); // 9 AM tomorrow

await client.setPushPreferences([
  {
    user_id: "user-1",
    channel_cid: "messaging:general",
    chat_level: "all",
    disabled_until: tomorrow.toISOString(),
  },
]);
```

```kotlin label="Kotlin"
// Disable push notifications for 2 hours for the current user
val twoHoursFromNow = Date().apply { time += 2.hours.inWholeMilliseconds }
client.snoozeUserPushNotifications(until = twoHoursFromNow).enqueue()

// Disable push notifications for a specific channel until tomorrow
val tomorrow = Date().apply { time += 1.days.inWholeMilliseconds }
client.snoozeChannelPushNotifications("messaging:general", until = tomorrow).enqueue()
```

```swift label="Swift"
// Disable push notifications for 2 hours for the current user
let twoHoursFromNow = Date().addingTimeInterval(2 * 60 * 60)
currentUserController.snoozePushNotifications(until: twoHoursFromNow)

// Disable push notifications for a specific channel until tomorrow
if let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date()) {
    channelController.snoozePushNotifications(until: tomorrow)
}
```

</Tabs>

### Granular Chat Preferences

For more fine-grained control, use the `chat_preferences` object instead of `chat_level`. This lets users toggle push notifications independently for each mention type.

<Admonition type="warning">

`chat_preferences` and `chat_level` are mutually exclusive. When `chat_preferences` is set, `chat_level` is cleared (and vice versa). Do not set both in the same request.

</Admonition>

#### Chat preferences fields

| Field                | Description                                         | Values        |
| -------------------- | --------------------------------------------------- | ------------- |
| `default_preference` | Fallback for categories that are not explicitly set | `all`, `none` |
| `direct_mentions`    | Direct user mentions (`mentioned_users`)            | `all`, `none` |
| `here_mentions`      | `@here` mentions (`mentioned_here`)                 | `all`, `none` |
| `channel_mentions`   | `@channel` mentions (`mentioned_channel`)           | `all`, `none` |
| `role_mentions`      | Role mentions (`mentioned_roles`)                   | `all`, `none` |
| `group_mentions`     | User group mentions (`mentioned_group_ids`)         | `all`, `none` |
| `thread_replies`     | Replies in threads                                  | `all`, `none` |

Each field is optional. When a field is unset (empty), the `default_preference` value is used. If `default_preference` is also unset, notifications are allowed.

#### How granular preferences are evaluated

When a message is sent, the system checks which mention categories apply to the recipient (e.g., they were directly mentioned, they have one of the mentioned roles, etc.). The preference for each applying category is checked in the below order:

1. If **any** applying category is set to `all`, the push is sent.
2. If **any** applying category is set to `none` (and none are `all`), the push is suppressed.
3. If no applying category has an explicit preference, `default_preference` is used.

#### Setting granular preferences

Granular preferences can be set at both user-level and channel-member level, following the same priority rules as `chat_level`.

<Tabs>

```js label="JavaScript"
// User-level: only receive pushes for direct mentions and thread replies
await client.setPushPreferences([
  {
    user_id: "user-1",
    chat_preferences: {
      default_preference: "none",
      direct_mentions: "all",
      thread_replies: "all",
    },
  },
]);

// Channel-member level: mute @channel and @here in a noisy channel
await client.setPushPreferences([
  {
    user_id: "user-1",
    channel_cid: "messaging:general",
    chat_preferences: {
      default_preference: "all",
      channel_mentions: "none",
      here_mentions: "none",
    },
  },
]);
```

```kotlin label="Kotlin"
// Client-side - can only update current user's preferences

// User-level: only receive pushes for direct mentions and thread replies
client.setUserChatPreferences(
    ChatPreferences(
        defaultPreference = ChatPreferenceToggle.none,
        directMentions = ChatPreferenceToggle.all,
        threadReplies = ChatPreferenceToggle.all,
    ),
).enqueue()

// Channel-member level: mute @channel and @here in a noisy channel
client.setChannelChatPreferences(
    cid = "messaging:general",
    preferences = ChatPreferences(
        defaultPreference = ChatPreferenceToggle.all,
        channelMentions = ChatPreferenceToggle.none,
        hereMentions = ChatPreferenceToggle.none,
    ),
).enqueue()
```

```python label="Python"
# User-level: only receive pushes for direct mentions and thread replies
client.set_push_preferences([
    {
        "user_id": "user-1",
        "chat_preferences": {
            "default_preference": "none",
            "direct_mentions": "all",
            "thread_replies": "all",
        },
    },
])

# Channel-member level: mute @channel and @here in a noisy channel
client.set_push_preferences([
    {
        "user_id": "user-1",
        "channel_cid": "messaging:general",
        "chat_preferences": {
            "default_preference": "all",
            "channel_mentions": "none",
            "here_mentions": "none",
        },
    },
])
```

</Tabs>

#### Switching between chat_level and chat_preferences

Setting `chat_preferences` clears any existing `chat_level`, and setting `chat_level` clears any existing `chat_preferences`. To switch back to `chat_level` after using granular preferences:

<Tabs>

```js label="JavaScript"
// Switch from granular preferences back to a simple level
await client.setPushPreferences([
  {
    user_id: "user-1",
    chat_level: "all_mentions",
  },
]);
```

```kotlin label="Kotlin"
// Switch from granular preferences back to a simple level
client.setUserPushPreference(PushPreferenceLevel("all_mentions")).enqueue()
```

</Tabs>

### Call Push Preferences

You can set preferences for call-related push notifications using the `call_level` field.

#### Call push preferences support two levels of notifications

- **all**: Receive all call push notifications **(default)**.
- **none**: Do not receive call push notifications.

#### Setting Call Push Preferences

<Tabs>

```js label="JavaScript"
// Set call-level preferences with temporary disabling
const oneHourFromNow = new Date(Date.now() + 60 * 60 * 1000);

await client.setPushPreferences([
  {
    user_id: "user-1",
    call_level: "all",
    disabled_until: oneHourFromNow.toISOString(),
  },
]);
```

</Tabs>

## Feeds Push Preferences

Push preferences for Activity Feeds allow users to control how they receive push notifications for feed events. You can set preferences at the user level to control notifications for reactions, comments, follows, and other feed activities.

### How Feeds Push Preferences Work

#### Feeds push preferences operate at the user level

- **User-level preferences**: Global preferences that apply to all feed activities for a user.
- **Event-specific preferences**: Granular control over specific types of feed events (reactions, comments, follows, mentions).

#### Feeds push preferences support two levels of notifications

- **all**: Receive all push notifications for feed events **(default)**.
- **none**: Do not receive push notifications for feed events.

Additionally, you can temporarily disable push notifications until a specific time using the `disabled_until` parameter.

#### The system evaluates preferences in the following priority order

1. **Global disabled_until**: If set and the current time is before that timestamp, all feed notifications are disabled.
2. **Feeds level**: If set to "none", all feed notifications are disabled.
3. **Event-specific preferences**: For specific event types (reactions, comments, follows), these override the global feeds level.
4. **Default behavior**: If no preferences are set, the default is "all".

### Setting Push Preferences

#### User-Level Feeds Preferences

Set global push preferences that apply to all feed activities for a user:

<Tabs>

```js label="React"
// Set basic feeds push level
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // "all" or "none"
    },
  ],
});
```

```js label="React Native"
// Set basic feeds push level
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // "all" or "none"
    },
  ],
});
```

```js label="JavaScript"
// Set basic feeds push level
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // "all" or "none"
    },
  ],
});
```

```kotlin label="Kotlin"
val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All // or None
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

#### Event-Specific Feeds Preferences

Control notifications for specific types of feed events:

<Tabs>

```js label="React"
// Set granular event preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Global feeds level
      feeds_preferences: {
        reaction: "all", // Receive notifications for reactions
        comment: "all", // Receive notifications for activity comments
        comment_reaction: "all", // Receive notifications for comment reactions
        follow: "none", // Don't receive notifications for new followers
        mention: "all", // Receive notifications for mentions
      },
    },
  ],
});
```

```js label="React Native"
// Set granular event preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Global feeds level
      feeds_preferences: {
        reaction: "all", // Receive notifications for reactions
        comment: "all", // Receive notifications for activity comments
        comment_reaction: "all", // Receive notifications for comment reactions
        follow: "none", // Don't receive notifications for new followers
        mention: "all", // Receive notifications for mentions
      },
    },
  ],
});
```

```js label="JavaScript"
// Set granular event preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Global feeds level
      feeds_preferences: {
        reaction: "all", // Receive notifications for reactions
        comment: "all", // Receive notifications for activity comments
        comment_reaction: "all", // Receive notifications for comment reactions
        follow: "none", // Don't receive notifications for new followers
        mention: "all", // Receive notifications for mentions
      },
    },
  ],
});
```

```kotlin label="Kotlin"
val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All, // Global feeds level
    feedsPreferences = FeedsPreferences(
        reaction = FeedsPreferences.Reaction.All, // Receive notifications for reactions
        comment = FeedsPreferences.Comment.All, // Receive notifications for activity comments
        commentReaction = FeedsPreferences.CommentReaction.All, // Receive notifications for comment reactions
        follow = FeedsPreferences.Follow.None, // Don't receive notifications for new followers
        mention = FeedsPreferences.Mention.All // Receive notifications for mentions

    )
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

#### Temporarily Disable Feeds Notifications

Disable all feed notifications until a specific time:

<Tabs>

```js label="React"
// Disable feeds notifications for 2 hours
const twoHoursFromNow = new Date();
twoHoursFromNow.setHours(twoHoursFromNow.getHours() + 2);

await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      disabled_until: twoHoursFromNow.toISOString(),
    },
  ],
});
```

```js label="React Native"
// Disable feeds notifications for 2 hours
const twoHoursFromNow = new Date();
twoHoursFromNow.setHours(twoHoursFromNow.getHours() + 2);

await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      disabled_until: twoHoursFromNow.toISOString(),
    },
  ],
});
```

```js label="JavaScript"
// Disable feeds notifications for 2 hours
const twoHoursFromNow = new Date();
twoHoursFromNow.setHours(twoHoursFromNow.getHours() + 2);

await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      disabled_until: twoHoursFromNow.toISOString(),
    },
  ],
});
```

```kotlin label="Kotlin"
val twoHoursFromNow = Calendar.getInstance()
    .apply { add(Calendar.HOUR_OF_DAY, 2) }
    .time

val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All,
    disabledUntil = twoHoursFromNow
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

### Feed Event Types

The following feed event types support granular push preferences:

#### Built-in Event Types

| Event Type        | Description                                        | Preference Key     |
| ----------------- | -------------------------------------------------- | ------------------ |
| Reactions         | When someone reacts to your activities or comments | `reaction`         |
| Comments          | When someone comments on your activities           | `comment`          |
| Comment Reactions | When someone reacts to your comments               | `comment_reaction` |
| New Followers     | When someone follows you                           | `follow`           |
| Mentions          | When you are mentioned in activities or comments   | `mention`          |

#### Custom Activity Types

You can also configure push preferences for any custom activity types using the `custom_activity_types` field:

<Tabs>

```js label="React"
await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all",
        comment: "all",
        comment_reaction: "all",
        follow: "none",
        mention: "all",
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_alert: "none", // Block system alert notifications
          promotion: "none", // Block promotional notifications
          custom_celebration: "all", // Allow custom celebration notifications
        },
      },
    },
  ],
});
```

```js label="React Native"
await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all",
        comment: "all",
        comment_reaction: "all",
        follow: "none",
        mention: "all",
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_alert: "none", // Block system alert notifications
          promotion: "none", // Block promotional notifications
          custom_celebration: "all", // Allow custom celebration notifications
        },
      },
    },
  ],
});
```

```js label="JavaScript"
await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "all",
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all",
        comment: "all",
        comment_reaction: "all",
        follow: "none",
        mention: "all",
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_alert: "none", // Block system alert notifications
          promotion: "none", // Block promotional notifications
          custom_celebration: "all", // Allow custom celebration notifications
        },
      },
    },
  ],
});
```

```kotlin label="Kotlin"
val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All,
    // Built-in event preferences
    feedsPreferences = FeedsPreferences(
        reaction = FeedsPreferences.Reaction.All,
        comment = FeedsPreferences.Comment.All,
        commentReaction = FeedsPreferences.CommentReaction.All,
        follow = FeedsPreferences.Follow.All,
        mention = FeedsPreferences.Mention.All,
        // Custom activity type preferences
        customActivityTypes = mapOf(
            "milestone" to "all", // Allow milestone notifications
            "achievement" to "all", // Allow achievement notifications
            "system_alert" to "none", // Block system alert notifications
            "promotion" to "none", // Block promotional notifications
            "custom_celebration" to "all", // Allow custom celebration notifications
        )
    )
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

**How Custom Activity Types Work:**

- Map any `activity.type` to a preference (`"all"` or `"none"`)
- Custom types not specified in the map default to `"all"`
- This gives you complete control over which custom events trigger push notifications

### Client-Side vs Server-Side Usage

#### Client-Side Usage

When using client-side authentication, users can only update their own preferences:

<Tabs>

```js label="React"
// Client-side: user_id is automatically set to the current user
await client.updatePushNotificationPreferences({
  preferences: [
    {
      // user_id not needed - automatically set to current user
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none",
        comment: "all",
      },
    },
  ],
});
```

```js label="React Native"
// Client-side: user_id is automatically set to the current user
await client.updatePushNotificationPreferences({
  preferences: [
    {
      // user_id not needed - automatically set to current user
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none",
        comment: "all",
      },
    },
  ],
});
```

```js label="JavaScript"
// Client-side: user_id is automatically set to the current user
await client.updatePushNotificationPreferences({
  preferences: [
    {
      // user_id not needed - automatically set to current user
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none",
        comment: "all",
      },
    },
  ],
});
```

```kotlin label="Kotlin"
// Client-side: user_id is automatically set to the current user
val input = PushPreferenceInput(
    // userId not needed - automatically set to current user
    feedsLevel = PushPreferenceInput.FeedsLevel.All,
    feedsPreferences = FeedsPreferences(
        reaction = FeedsPreferences.Reaction.None,
        comment = FeedsPreferences.Comment.All,
    )
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

#### Server-Side Usage

With server-side authentication, you can update preferences for any user:

<Tabs>

```js label="Node.js"
// Server-side: can update preferences for any user
await client.updatePushNotificationPreferences({
  preferences: [
    {
      user_id: "user-1",
      feeds_level: "none",
    },
    {
      user_id: "user-2",
      feeds_preferences: {
        reaction: "all",
        comment: "none",
        follow: "all",
      },
    },
  ],
});
```

```php label="PHP"
// Update push notification preferences for multiple users
$response = $client->updatePushNotificationPreferences(
    new \GetStream\GeneratedModels\UpsertPushPreferencesRequest([
        'preferences' => [
            new \GetStream\GeneratedModels\PushPreferenceInput(
                userID: "user-1",
                feedsLevel: "none"
            ),
            new \GetStream\GeneratedModels\PushPreferenceInput(
                userID: "user-2",
                feedsLevel: "all",
                feedsPreferences: new \GetStream\GeneratedModels\FeedsPreferences(
                    reaction: "all",
                    comment: "none",
                    follow: "all"
                )
            ),
        ]
    ])
);
```

```go label="Go"
// Update push notification preferences for multiple users
_, err = client.UpdatePushNotificationPreferences(ctx, &getstream.UpdatePushNotificationPreferencesRequest{
  Preferences: []getstream.PushPreferenceInput{
    {
      UserID:     getstream.PtrTo("user-1"),
      FeedsLevel: getstream.PtrTo("none"),
    },
    {
      UserID: getstream.PtrTo("user-2"),
      FeedsEvents: &getstream.FeedsEventPreferencesInput{
        Reactions: getstream.PtrTo("all"),
        Comments:  getstream.PtrTo("none"),
        NewFollowers: getstream.PtrTo("all"),
      },
    },
  },
})

if err != nil {
  log.Fatal("Error updating push notification preferences:", err)
}
```

</Tabs>

### Follow Push Preferences

When following users or feeds, you can set push preferences to control notifications for future activities from those feeds.

#### Setting Follow Push Preferences

<Tabs>

```js label="React"
// Follow with push preference for all activities
await timeline.follow("user:alice", {
  push_preference: "all", // Receive notifications for Alice's future activities
});

// Follow with no push notifications for activities
await timeline.follow("user:bob", {
  push_preference: "none", // Don't receive notifications for Bob's activities
});
```

```js label="React Native"
// Follow with push preference for all activities
await timeline.follow("user:alice", {
  push_preference: "all", // Receive notifications for Alice's future activities
});

// Follow with no push notifications for activities
await timeline.follow("user:bob", {
  push_preference: "none", // Don't receive notifications for Bob's activities
});
```

```js label="JavaScript"
// Follow with push preference for all activities
await timeline.follow("user:alice", {
  push_preference: "all", // Receive notifications for Alice's future activities
});

// Follow with no push notifications for activities
await timeline.follow("user:bob", {
  push_preference: "none", // Don't receive notifications for Bob's activities
});
```

```kotlin label="Kotlin"
// Follow with push preference for all activities
timeline.follow(
    targetFid = FeedId("user:alice"),
    // Receive notifications for Alice's future activities
    pushPreference = FollowRequest.PushPreference.All,
)

// Follow with no push notifications for activities
timeline.follow(
    targetFid = FeedId("user:bob"),
    // Don't receive notifications for Bob's activities
    pushPreference = FollowRequest.PushPreference.None
)
```

</Tabs>

#### Follow Push Preference Options

| Value  | Description                                                                          |
| ------ | ------------------------------------------------------------------------------------ |
| `all`  | Receive push notifications for all activities from the followed feed                 |
| `none` | Don't receive push notifications for activities from the followed feed **(default)** |

**Note:** Follow push preferences are different from user-level push preferences:

- **Follow push preferences** control notifications from specific feeds you follow
- **User-level push preferences** control global notification settings for all feeds

### Examples

#### Complete Feeds Preferences Setup

<Tabs>

```js label="React"
// Set comprehensive feeds preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Enable feeds notifications globally
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all", // Get notified of all activity reactions
        comment: "all", // Get notified of all comments
        comment_reaction: "all", // Get notified of all comment reactions
        follow: "none", // Don't notify for new followers
        mention: "all", // Get notified when mentioned
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_maintenance: "none", // Block maintenance notifications
          promotional_offer: "none", // Block promotional notifications
        },
      },
    },
  ],
});
```

```js label="React Native"
// Set comprehensive feeds preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Enable feeds notifications globally
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all", // Get notified of all activity reactions
        comment: "all", // Get notified of all comments
        comment_reaction: "all", // Get notified of all comment reactions
        follow: "none", // Don't notify for new followers
        mention: "all", // Get notified when mentioned
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_maintenance: "none", // Block maintenance notifications
          promotional_offer: "none", // Block promotional notifications
        },
      },
    },
  ],
});
```

```js label="JavaScript"
// Set comprehensive feeds preferences
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all", // Enable feeds notifications globally
      feeds_preferences: {
        // Built-in event preferences
        reaction: "all", // Get notified of all activity reactions
        comment: "all", // Get notified of all comments
        comment_reaction: "all", // Get notified of all comment reactions
        follow: "none", // Don't notify for new followers
        mention: "all", // Get notified when mentioned
        // Custom activity type preferences
        custom_activity_types: {
          milestone: "all", // Allow milestone notifications
          achievement: "all", // Allow achievement notifications
          system_maintenance: "none", // Block maintenance notifications
          promotional_offer: "none", // Block promotional notifications
        },
      },
    },
  ],
});
```

```kotlin label="Kotlin"
// Set comprehensive feeds preferences
val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All, // Enable feeds notifications globally
    feedsPreferences = FeedsPreferences(
        // Built-in event preferences
        reaction = FeedsPreferences.Reaction.All, // Get notified of all activity reactions
        comment = FeedsPreferences.Comment.All, // Get notified of all comments
        commentReaction = FeedsPreferences.CommentReaction.All, // Get notified of all comment reactions
        follow = FeedsPreferences.Follow.None, // Don't notify for new followers
        mention = FeedsPreferences.Mention.All, // Get notified when mentioned
        // Custom activity type preferences
        customActivityTypes = mapOf(
            "milestone" to "all", // Allow milestone notifications
            "achievement" to "all", // Allow achievement notifications
            "system_maintenance" to "none", // Block maintenance notifications
            "promotional_offer" to "none", // Block promotional notifications
        )
    )
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

#### Do Not Disturb Mode for Feeds

<Tabs>

```js label="React"
// Enable "Do Not Disturb" for feeds until tomorrow
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(9, 0, 0, 0); // 9 AM tomorrow

await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "none",
      disabled_until: tomorrow.toISOString(),
    },
  ],
});
```

```js label="React Native"
// Enable "Do Not Disturb" for feeds until tomorrow
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(9, 0, 0, 0); // 9 AM tomorrow

await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "none",
      disabled_until: tomorrow.toISOString(),
    },
  ],
});
```

```js label="JavaScript"
// Enable "Do Not Disturb" for feeds until tomorrow
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(9, 0, 0, 0); // 9 AM tomorrow

await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "none",
      disabled_until: tomorrow.toISOString(),
    },
  ],
});
```

```kotlin label="Kotlin"
// Enable "Do Not Disturb" for feeds until 9 AM tomorrow
val tomorrow = Calendar.getInstance()
    .apply {
        add(Calendar.DAY_OF_MONTH, 1)
        set(Calendar.HOUR_OF_DAY, 9)
        set(Calendar.MINUTE, 0)
        set(Calendar.SECOND, 0)
        set(Calendar.MILLISECOND, 0)
    }
    .time

val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.None,
    disabledUntil = tomorrow
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>

#### Minimal Feeds Notifications

<Tabs>

```js label="React"
// Only get notified for comments and mentions
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none", // Skip reaction notifications
        comment: "all", // Keep comment notifications
        follow: "none", // Skip follower notifications
        mention: "all", // Keep mention notifications
      },
    },
  ],
});
```

```js label="React Native"
// Only get notified for comments and mentions
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none", // Skip reaction notifications
        comment: "all", // Keep comment notifications
        follow: "none", // Skip follower notifications
        mention: "all", // Keep mention notifications
      },
    },
  ],
});
```

```js label="JavaScript"
// Only get notified for comments and mentions
await client.updatePushNotificationPreferences({
  preferences: [
    {
      feeds_level: "all",
      feeds_preferences: {
        reaction: "none", // Skip reaction notifications
        comment: "all", // Keep comment notifications
        follow: "none", // Skip follower notifications
        mention: "all", // Keep mention notifications
      },
    },
  ],
});
```

```kotlin label="Kotlin"
// Only get notified for comments and mentions
val input = PushPreferenceInput(
    feedsLevel = PushPreferenceInput.FeedsLevel.All,
    feedsPreferences = FeedsPreferences(
        reaction = FeedsPreferences.Reaction.None, // Skip reaction notifications
        comment = FeedsPreferences.Comment.All, // Keep comment notifications
        follow = FeedsPreferences.Follow.None, // Skip follower notifications
        mention = FeedsPreferences.Mention.All // Keep mention notifications
    )
)
client.updatePushNotificationPreferences(
    UpsertPushPreferencesRequest(preferences = listOf(input))
)
```

</Tabs>


---

This page was last updated at 2026-08-10T16:01:01.345Z.

For the most recent version of this documentation, visit [https://getstream.io/docs/platform/push-preferences/](https://getstream.io/docs/platform/push-preferences/).