# Updating Channel Members

### Adding & Removing Channel Members

Using the `addMembers()` method adds the given users as members, while `removeMembers()` removes them.

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val channelClient = client.channel("messaging", "general")

// Add members with ids "thierry" and "josh"
channelClient.addMembers(listOf("thierry", "josh")).enqueue { result ->
  if (result is Result.Success) {
    val channel: Channel = result.value
  } else {
    // Handle Result.Failure
  }
}

// Add member "thierry" with custom data with key: "code_name" and value "007"
val params = AddMembersParams(
  members = listOf(
    MemberData(userId = "thierry", extraData = mapOf("code_name" to "007")),
  ),
)
channelClient.addMembers(params).enqueue { result ->
  if (result is Result.Success) {
    val channel: Channel = result.value
  } else {
    // Handle Result.Failure
  }
}

// Remove member with id "tommaso"
channelClient.removeMembers(listOf("tommaso")).enqueue { result ->
  if (result is Result.Success) {
    val channel: Channel = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await channel.addMembers(["thierry", "josh"]);
await channel.removeMembers(["tommaso"]);

// Add user to the channel with role set
await channel.addMembers([
  { user_id: "james_bond", channel_role: "channel_moderator" },
]);

// Add new channel member with custom data
await channel.addMembers([{ user_id: "james_bond", code_name: "007" }]);
```

</codetabs-item>

<codetabs-item value="dart" label="Dart">

```dart
await channel.addMembers(["thierry", "josh"]);
await channel.removeMembers(["tommaso"]);
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
$channel->addMembers(['thierry', 'jenny']);
$channel->removeMembers(['thierry', 'jenny']);
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
import Stream Chat

let controller = chatClient.channelController(for: .init(type: .messaging, id: "general"))

controller.addMembers(userIds: ["thierry", "josh"])
controller.removeMembers(userIds: ["tommaso"])
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
err := channel.AddMembers([]string{"thierry"}, nil, nil)
```

</codetabs-item>

<codetabs-item value="unreal" label="Unreal">

```cpp
Channel->AddMembers({TEXT("thierry"), TEXT("josh")});
Channel->RemoveMembers({TEXT("tommaso")});
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
channel.add_members(["thierry", "josh"])
channel.remove_members(["tommaso"])
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
await channelClient.AddMembersAsync("channel-type", "channel-id", "thierry", "josh");

await channelClient.RemoveMembersAsync("channel-type", "channel-id", new[] { "thierry", "josh" });
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# require 'stream-chat'

channel.add_members(["thierry", "josh"])
channel.remove_members(["tommaso"])
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Android SDK

ChannelClient channelClient = client.channel("messaging", "general");

// Add members with ids "thierry" and "josh"
channelClient.addMembers(Arrays.asList("thierry", "josh"), null).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
});

// Remove member with id "tommaso"
channelClient.removeMembers(Arrays.asList("tommaso"), null).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
 });

// Backend SDK

// Add members with ids "thierry" and "josh"
Channel.update("messaging", "general")
  .addMembers(Arrays.asList("thierry", "josh"))
  .request();
});

// Remove member with id "tommaso"
Channel.update("messaging", "general")
  .removeMember("tommaso")
  .request();
});
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
var channel = await Client.GetOrCreateChannelWithIdAsync(ChannelType.Messaging, channelId: "my-channel-id");

var filters = new IFieldFilterRule[]
{
  UserFilter.Id.In("other-user-id-1", "other-user-id-2", "other-user-id-3")
};

var users = await Client.QueryUsersAsync(filters);

// Add IStreamUser collection as a members
await channel.AddMembersAsync(users);

// Or add by ID
await channel.AddMembersAsync("some-user-id-1", "some-user-id-2");

// Access channel members via channel.Members, let's remove the first member as an example
var member = channel.Members.First();
await channel.RemoveMembersAsync(member);

// Remove local user from a channel by user ID
var localUser = Client.LocalUserData.User;
await channel.RemoveMembersAsync(localUser.Id);

// Remove multiple users by their ID
await channel.RemoveMembersAsync("some-user-id-1", "some-user-id-2");
```

</codetabs-item>

</codetabs>

<admonition type="info">

**Note:** You can only add/remove up to 100 members at once.

</admonition>

Members can also be added while creating the channel.

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val channelClient = client.channel("messaging", "general")

// Add members with ids "james_bond", "alec_trevelyan" and "bill_fairbanks"
// during channel creation
channelClient.create(
  memberIds = listOf("james_bond", "alec_trevelyan", "bill_fairbanks"),
  extraData = emptyMap(),
).enqueue()

// Add members with custom extra data during channel creation
val params = CreateChannelParams(
  members = listOf(
    MemberData(userId = "james_bond", extraData = mapOf("code_name" to "007")),
    MemberData(userId = "alec_trevelyan", extraData = mapOf("code_name" to "006")),
    MemberData(userId = "bill_fairbanks", extraData = mapOf("code_name" to "007")),
  ),
  extraData = emptyMap(),
)
channelClient.create(params).enqueue()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
const channel = client.channel('messaging', randomID, {
  members: [
    { user_id: "james_bond", code_name: "007" },
    { user_id: "alec_trevelyan", code_name: "006" },
    { user_id: "bill_fairbanks", code_name: "002" },
});
await channel.create();
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
/// 1: Use the `ChatClient` to create a `ChatChannelController` with a list of user ids
let channelId = ChannelId(type: .messaging, id: "general")
let channelController = try chatClient.channelController(
  createChannelWithId: channelId,
  members: ["thierry", "tommaso"]
)
/// 2: Call `ChatChannelController.synchronize` to create the channel.
channelController.synchronize { error in
  if let error = error {
    /// 4: Handle possible errors
    print(error)
  }
}
```

</codetabs-item>

</codetabs>

#### Message parameter

You can optionally include a message object that client-side SDKs will use to populate a system message. This works for both add and remove members

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
val channelClient = client.channel("messaging", "general")

// Add members with ids "thierry" and "josh"
channelClient.addMembers(
  listOf("thierry", "josh"),
  Message(text = "Thierry and Josh joined this channel."),
).enqueue()

// Add members with custom extra data and a system message
val params = AddMembersParams(
  members = listOf(
    MemberData(userId = "thierry", extraData = mapOf("new_member" to true)),
    MemberData(userId = "josh", extraData = mapOf("new_member" to true)),
  ),
  systemMessage = Message(text = "Thierry and Josh joined this channel."),
)
channelClient.addMembers(params).enqueue()

// Remove member with id "tommaso"
channelClient.removeMembers(
  listOf("tommaso"),
  Message(text = "Tommaso was removed from this channel."),
).enqueue()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// using client-side client
await channel.addMembers(["tommaso"], { text: "Tommaso joined the channel." });
// using server-side client
await channel.addMembers(["tommaso"], {
  text: "Tommaso joined the channel.",
  user_id: "tommaso",
});
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
err := channel.AddMembers([]string{"tommaso"}, &Message{Text: "Tommaso joined the channel.", User: &User{ID: "tommaso"}}, nil)
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
channel.add_members(["tommaso", "josh"], { "text": 'Tommaso joined the channel.', "user_id": 'tommaso' })
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
$channel->addMembers(['tommaso'], ["message" =>
  ["text" => "Tommaso joined the channel.", "user_id" => "tommaso"]
 ]);
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
var msg = new MessageRequest { Text: "Tommaso joined the channel", UserId: "tommaso" };
await channelClient.AddMembersAsync("channel-type", "channel-id", new[] {"tommaso"}, msg, null);
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
channel.add_members(["tommaso", "josh"], message: { "text" => 'Tommaso joined the channel.', "user_id" => 'tommaso' })
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Android SDK
ChannelClient channelClient = client.channel("messaging", "general");

Message addMemberSystemMessage = new Message();
addMemberSystemMessage.setText("Thierry and Josh were added to this channel");
// Add members with ids "thierry" and "josh"
channelClient.addMembers(Arrays.asList("thierry", "josh"), addMemberSystemMessage).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
});

Message removeMemberSystemMessage = new Message();
addMemberSystemMessage.setText("Tommaso was removed from this channel");
// Remove member with id "tommaso"
channelClient.removeMembers(Arrays.asList("tommaso"), removeMemberSystemMessage).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
 });

// Backend SDK
MessageRequestObject msg = MessageRequestObject
  .builder()
    .text("Thierry and Josh were added to this channel")
  .build();
// Add members with ids "thierry" and "josh"
ChannelUpdateResponse resp = Channel.update("messaging", "general")
  .addMembers(Arrays.asList("thierry", "josh"))
  .message(msg)
  .request();

MessageRequestObject msg = MessageRequestObject
  .builder()
    .text("Tommaso was removed from this channel")
  .build();
// Remove member with id "tommaso"
ChannelUpdateResponse resp = Channel.update("messaging", "general")
  .removeMember("tommaso")
  .message(msg)
  .request();
```

</codetabs-item>

<codetabs-item value="unreal" label="Unreal">

```cpp
Channel->AddMembers({TEXT("tommaso")}, FMessage{TEXT("Tommaso joined the channel.")});
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
await channel.AddMembersAsync(users, hideHistory: default, new StreamMessageRequest
{
  Text = "John has joined the channel"
});
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
channelController.addMembers(
  userIds: ["tommaso"],
  message: "Tommaso joined the channel"
) { error in
  // …
}
```

</codetabs-item>

</codetabs>

#### Hide history

When members join a channel you can specify if they have access to the history or not. The history will be shown by default, set `true` to `hide_history` parameter to hide it for new members.

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
// Add members by their IDs with hideHistory=true
channelClient.addMembers(
  memberIds = listOf("thierry"),
  hideHistory = true,
).enqueue()

// Add members by their IDs with hideHistory=true and custom extra data
val params = AddMembersParams(
  members = listOf(
    MemberData(userId = "thierry", extraData = mapOf("new_member" to true)),
  ),
  hideHistory = true,
)
channelClient.addMembers(params).enqueue()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
await channel.addMembers(["thierry"], undefined, { hide_history: true });
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
options := map[string]interface{}{
 "hide_history": true,
 }
err := channel.AddMembers([]string{"thierry"}, nil, options)
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
channel.add_members(["thierry"], hide_history=True)
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
$channel->addMembers(["thierry"], ["hide_history" => true]);
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
await channelClient.AddMembersAsync("channel-type", "channel-id", new[] {"thierry"}, null, new AddMemberOptions { HideHistory = true })
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
channel.add_members(["tommaso", "josh"], hide_history: true)
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Backend SDK
Channel.update("channel-type", "channel-type")
  .addMember("thierry")
  .hideHistory(true)
  .request();
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
await channel.AddMembersAsync(users, hideHistory: true);
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
channelController.addMembers(
  userIds: ["thierry"],
  hideHistory: true
) { error in
  // …
}
```

</codetabs-item>

</codetabs>

### Leaving a channel

It is possible for user to leave the channel without moderator-level permissions. Make sure channel members have `Leave Own Channel` permission.

<codetabs>

<codetabs-item value="kotlin" label="Kotlin">

```kotlin
channelClient.removeMembers(listOf("my_user_id")).enqueue()
```

</codetabs-item>

<codetabs-item value="javascript" label="JavaScript">

```js
// remove own channel membership
await channel.removeMembers(["my_user_id"]);
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
resp, err := ch.RemoveMembers(ctx, []string{"my_user_id"})
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
channel.remove_members(["my_user_id"])
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
$channel->removeMembers(['my_user_id']);
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
await channelClient.RemoveMembersAsync("channel-type", "channel-id", new[] { "my_user_id" });
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
channel.remove_members(["my_user_id"])
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Backend SDK
Channel.update("channel-type", "channel-type")
  .removeMember("my_user_id")
  .request();
```

</codetabs-item>

<codetabs-item value="unreal" label="Unreal">

```cpp
Channel->RemoveMembers({TEXT("my-user-id")});
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
await channel.RemoveMembersAsync(member);
```

</codetabs-item>

<codetabs-item value="swift" label="Swift">

```swift
channelController.removeMembers(
  userIds: ["john"]
) { error in
  // …
}
```

</codetabs-item>

</codetabs>

<admonition type="info">

You can familiarize yourself with all permissions in [Permissions section](/chat/docs/<framework>/chat_permission_policies/)

</admonition>

### Adding & Removing Moderators to a Channel

Using the `addModerators()` method adds the given users as moderators (or updates their role to moderator if already members), while `demoteModerators()` removes the moderator status.

<codetabs>

<codetabs-item value="javascript" label="JavaScript">

```js
await channel.addModerators(["thierry", "josh"]);
await channel.demoteModerators(["tommaso"]);
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
channel.add_moderators(["thierry", "josh"]);
channel.demote_moderators(["tommaso"]);
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
channel.add_moderators(["thierry", "josh"])
channel.demote_moderators(["tommaso"])
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
$channel->addModerators(['thierry', 'jenny']);
$channel->demoteModerators(['thierry', 'jenny']);
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Backend SDK
Channel.update("channel-type", "channel-type").addModerator("thierry").addModerator("josh").request();
Channel.update("channel-type", "channel-type").demoteModerator("tommaso").request();
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
await channelClient.AddModeratorsAsync("channel-type", "channel-type", new[] { "thierry", "josh" });
await channelClient.DemoteModeratorsAsync("channel-type", "channel-type", new[] { "tommaso" });
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
newModerators := []string{"bob", "sue"}
err = channel.AddModerators("thierry", "josh")
err = channel.AddModerators(newModerators...)
err = channel.DemoteModerators(newModerators...)
```

</codetabs-item>

<codetabs-item value="unity" label="Unity">

```csharp
// Will be implemented soon, raise a GitHub issue if you need this feature https://github.com/GetStream/stream-chat-unity/issues/
```

</codetabs-item>

</codetabs>

<admonition type="info">

These operations can only be performed server-side and up to 100 moderators can be added or removed at once.

</admonition>

---

This page was last updated at 2025-08-15T14:14:30.282Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/go-golang/channel_members/](https://getstream.io/chat/docs/go-golang/channel_members/).