---
source_url: https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/users/moderation-user
title: Moderate misbehaving users as a chat user
updated_at: 2026-06-05T11:09:59.644Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Moderate misbehaving users as a chat user

Regular chat users (without `secretKey`) can mute undesirable users to hide their messages on the client side.

**Mute list behavior:**

* Soft limit: 200 users
* Default: session-only persistence
* Optional: persist across sessions (32 KiB server limit applies)

:::warning Mute list limit
Persisted lists exceeding 32 KiB (~200 users) trigger HTTP 413 errors. Users remain muted for the session but won't persist.
:::

**Affected methods:**

* [channel.onMessageReceived()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/channels/watch)
* [channel.join()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/channels/join)
* [channel.getHistory()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/history)
* [chat.listenForEvents()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/custom-events#receive-current-events)
* [chat.getEventsHistory()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/custom-events#get-historical-events)

:::note Requires App Context
Enable [App Context](https://youtu.be/9UEoSlngpYI) in the [Admin Portal](https://admin.pubnub.com/) to mute users.
:::

## Mute users as a regular chat user

Mute a specific user on all channels.

### Method signature

#### Async/await

```swift
func muteUser(userId: String) async throws
```

#### Closure

```swift
func muteUser(
  userId: String, 
  completion: ((Result<Void, Error>) -> Void)?
)
```

#### Input

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| userId | String | Yes |  | [User ID](https://www.pubnub.com/docs/general/setup/users-and-devices) of the user you want to mute. |
| completion | ((Result<Void, | Optional |  | Completion closure called with the result of the operation. |

#### Output

This method calls the completion closure with a `Result<Void, Error>` that succeeds when the data has been synced with the server. If [syncMutedUsers](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/configuration#sync-muted-users) is not enabled, the completion always succeeds.

#### Errors

If the size of the mute list exceeds 32 KiB (roughly 200 users), you'll get the `HTTP 413 (Request Entity Too Large)` error.

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

###### Async/await

```swift
let userToMute = "user_rks"
Task {
  do {
    try await chat.mutedUsersManager.muteUser(userId: userToMute)
    print("User muted successfully")
  } catch {
    print("Failed to mute user: \(error)")
  }
}
```

###### Closure

```swift
// Assumes a "ChatImpl" reference named "chat"
let userToMute = "user_rks"
chat.mutedUsersManager.muteUser(userId: userToMute) { result in
  switch result {
  case .success:
    print("User muted successfully")
  case .failure(let error):
    print("Failed to mute user: \(error)")
  }
}
```

## Unmute users as a regular chat user

Remove a user from the mute list to see their messages and events again.

### Method signature

#### Async/await

```swift
func unmuteUser(userId: String) async throws
```

#### Closure

```swift
func unmuteUser(
  userId: String, 
  completion: ((Result<Void, Error>) -> Void)?
)
```

#### Input

| Parameter | Description |
| --- | --- |
| `userId` *Type: `String` | [User ID](https://www.pubnub.com/docs/general/setup/users-and-devices) of the user you want to unmute. |
| `completion`Type: `((Result<Void, Error>) -> Void)?` | Completion closure called with the result of the operation. |

#### Output

This method calls the completion closure with a `Result<Void, Error>` that succeeds when the data has been synced with the server. If [syncMutedUsers](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/configuration#sync-muted-users) is not enabled, the completion always succeeds.

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

###### Async/await

```swift
let userToUnmute = "user_rks"
Task {
  do {
    try await chat.mutedUsersManager.unmuteUser(userId: userToUnmute)
    print("User unmuted successfully")
  } catch {
    print("Failed to unmute user: \(error)")
  }
}
```

###### Closure

```swift
// Assumes a "ChatImpl" reference named "chat"
let userToUnmute = "user_rks"
chat.mutedUsersManager.unmuteUser(userId: userToUnmute) { result in
  switch result {
  case .success:
    print("User unmuted successfully")
  case .failure(let error):
    print("Failed to unmute user: \(error)")
  }
}
```

## Check muted users

Inspect the mute list to see which users are muted.

### Method signature

```swift
var mutedUsers: Set<String> { get }
```

#### Output

This property returns a `Set<String>` where each `String` is a user ID of a muted user.

### Sample code

```swift
// Assumes a "ChatImpl" reference named "chat"
for userId in chat.mutedUsersManager.mutedUsers {
  print("Muted user: \(userId)")
}
```

## Persist the mute list

Set `syncMutedUsers: true` during [client initialization](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/configuration#initialize-pubnub) to persist the mute list across sessions.

:::warning Access Manager permissions
With Access Manager and `syncMutedUsers` enabled, grant these permissions (replace `$currentUserId` with the actual user ID):
* `read` on `PN_PRIV.$currentUserId.mute1` channel
* `update`, `delete`, `get` on `PN_PRIV.$currentUserId.mute1` user
:::

## Listen to restriction changes

`onRestrictionChanged()` notifies the current user whenever an admin changes their mute or ban status on any channel. Use this to react in real time — for example, to show a notification or adjust UI when the user is muted or banned.

You can also use `user.stream.restrictionChanges()` for an `AsyncStream`-based approach.

### Method signature

```swift
user.onRestrictionChanged(
    callback: @escaping (Restriction) -> Void
) -> AutoCloseable
```

The `Restriction` struct carries the restriction payload:

```swift
public struct Restriction {
    public let userId: String
    public let channelId: String
    public let ban: Bool
    public let mute: Bool
    public let reason: String?
}
```

#### Input

| Parameter | Description |
| --- | --- |
| `callback` *Type: `(Restriction) -> Void`Default: n/a | Closure called with a `Restriction` whenever the user's moderation status changes on a channel. |

#### Output

| Parameter | Description |
| --- | --- |
| `AutoCloseable` | An object you must retain. When released or closed, the listener stops. |