# Channel Members

Channel members are users who have been added to a channel and can participate in conversations. This page covers how to manage channel membership, including adding and removing members, controlling message history visibility, and managing member roles.

## Adding and Removing Members

### Adding Members

Using the `addMembers()` method adds the given users as members to a channel.

<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
  }
}
```

</codetabs-item>

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

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

// 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"]);
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    addMembers: [
        new Models\ChannelMemberRequest(userID: "thierry"),
        new Models\ChannelMemberRequest(userID: "jenny"),
    ],
));
```

</codetabs-item>

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

```swift
import StreamChat

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

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

</codetabs-item>

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

```go
channel := client.Chat().Channel("messaging", "general")

channel.Update(ctx, &getstream.UpdateChannelRequest{
	AddMembers: []getstream.ChannelMemberRequest{
		{UserID: "thierry"},
		{UserID: "josh"},
	},
})
```

</codetabs-item>

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

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

</codetabs-item>

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

```python
from getstream.models import ChannelMemberRequest

channel.update(
    add_members=[
        ChannelMemberRequest(user_id="thierry"),
        ChannelMemberRequest(user_id="josh"),
    ],
)
```

</codetabs-item>

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

```csharp
using GetStream;
using GetStream.Models;

var client = new StreamClient("{{ api_key }}", "{{ api_secret }}");
var chat = new ChatClient(client);

await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        AddMembers = new List<ChannelMemberRequest>
        {
            new ChannelMemberRequest { UserID = "thierry" },
            new ChannelMemberRequest { UserID = "josh" }
        }
    });
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  add_members: [
    Models::ChannelMemberRequest.new(user_id: "thierry"),
    Models::ChannelMemberRequest.new(user_id: "josh"),
  ],
))
```

</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()
  }
});

// Backend SDK
chat.updateChannel("messaging", "general", UpdateChannelRequest.builder()
    .addMembers(List.of(
        ChannelMemberRequest.builder().userID("thierry").build(),
        ChannelMemberRequest.builder().userID("josh").build()))
    .build()).execute();
```

</codetabs-item>

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

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

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

// Or add by ID
await channel.AddMembersAsync("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 when creating a channel:

<codetabs>

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

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

// Add members 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")),
  ),
  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" },
  ],
});
await channel.create();
```

</codetabs-item>

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

```swift
let channelId = ChannelId(type: .messaging, id: "general")
let channelController = try chatClient.channelController(
  createChannelWithId: channelId,
  members: ["thierry", "tommaso"]
)
channelController.synchronize { error in
  if let error = error {
    print(error)
  }
}
```

</codetabs-item>

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

```csharp
// Members can be added when creating a channel
var resp = await chat.GetOrCreateChannelAsync("messaging", "my-channel-id",
    new ChannelGetOrCreateRequest
    {
        Data = new ChannelInput
        {
            CreatedByID = "user-1",
            Members = new List<ChannelMemberRequest>
            {
                new ChannelMemberRequest { UserID = "user-1" },
                new ChannelMemberRequest { UserID = "user-2" },
                new ChannelMemberRequest { UserID = "user-3" }
            }
        }
    });
```

</codetabs-item>

</codetabs>

### Removing Members

Using the `removeMembers()` method removes the given users from the channel.

<codetabs>

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

```kotlin
// 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.removeMembers(["tommaso"]);
```

</codetabs-item>

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

```dart
await channel.removeMembers(["tommaso"]);
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    removeMembers: ["thierry", "jenny"],
));
```

</codetabs-item>

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

```swift
controller.removeMembers(userIds: ["tommaso"])
```

</codetabs-item>

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

```cpp
Channel->RemoveMembers({TEXT("tommaso")});
```

</codetabs-item>

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

```python
channel.update(remove_members=["tommaso"])
```

</codetabs-item>

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

```csharp
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        RemoveMembers = new List<string> { "thierry", "josh" }
    });
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  remove_members: ["tommaso"],
))
```

</codetabs-item>

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

```java
// Android SDK
channelClient.removeMembers(Arrays.asList("tommaso"), null).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
});

// Backend SDK
chat.updateChannel("messaging", "general", UpdateChannelRequest.builder()
    .removeMembers(List.of("tommaso"))
    .build()).execute();
```

</codetabs-item>

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

```csharp
// Access channel members via channel.Members
var member = channel.Members.First();
await channel.RemoveMembersAsync(member);

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

</codetabs-item>

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

```go
channel.Update(ctx, &getstream.UpdateChannelRequest{
	RemoveMembers: []string{"tommaso"},
})
```

</codetabs-item>

</codetabs>

### Leaving a Channel

Users can leave a channel without moderator-level permissions. Ensure channel members have the `Leave Own Channel` permission enabled.

<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="swift" label="Swift">

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

</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>

<admonition type="info">

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

</admonition>

## Hide History

When members join a channel, you can specify whether they have access to the channel's message history. By default, new members can see the history. Set `hide_history` to `true` 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
channel.Update(ctx, &getstream.UpdateChannelRequest{
	AddMembers:  []getstream.ChannelMemberRequest{{UserID: "thierry"}},
	HideHistory: getstream.PtrTo(true),
})
```

</codetabs-item>

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

```python
from getstream.models import ChannelMemberRequest

channel.update(
    add_members=[ChannelMemberRequest(user_id="thierry")],
    hide_history=True,
)
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    addMembers: [new Models\ChannelMemberRequest(userID: "thierry")],
    hideHistory: true,
));
```

</codetabs-item>

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

```csharp
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        AddMembers = new List<ChannelMemberRequest>
        {
            new ChannelMemberRequest { UserID = "thierry" }
        },
        HideHistory = true
    });
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  add_members: [
    Models::ChannelMemberRequest.new(user_id: "tommaso"),
    Models::ChannelMemberRequest.new(user_id: "josh"),
  ],
  hide_history: true,
))
```

</codetabs-item>

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

```java
// Backend SDK
chat.updateChannel("channel-type", "channel-id", UpdateChannelRequest.builder()
    .addMembers(List.of(ChannelMemberRequest.builder().userID("thierry").build()))
    .hideHistory(true)
    .build()).execute();
```

</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>

### Hide History Before a Specific Date

Alternatively, `hide_history_before` can be used to hide any history before a given timestamp while giving members access to later messages. The value must be a timestamp in the past in RFC 3339 format. If both parameters are defined, `hide_history_before` takes precedence over `hide_history`.

<codetabs>

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

```kotlin
val cutoff = Date()
cutoff.time -= 7.days.inWholeMilliseconds
channelClient
  .addMembers(memberIds = listOf("thierry"), hideHistoryBefore = cutoff)
  .enqueue()
```

</codetabs-item>

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

```js
const cutoff = new Date();
cutoff.setDate(date.getDate() - 7); // Last 7 days
await channel.addMembers(["thierry"], undefined, {
  hide_history_before: cutoff.toISOString(),
});
```

</codetabs-item>

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

```go
t := time.Now().Add(-7 * 24 * time.Hour)
cutoff := getstream.Timestamp{Time: &t}
channel.Update(ctx, &getstream.UpdateChannelRequest{
	AddMembers:        []getstream.ChannelMemberRequest{{UserID: "thierry"}},
	HideHistoryBefore: &cutoff,
})
```

</codetabs-item>

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

```python
from datetime import datetime, timedelta, timezone
from getstream.models import ChannelMemberRequest

cutoff = datetime.now(timezone.utc) - timedelta(days=7)  # Last 7 days
channel.update(
    add_members=[ChannelMemberRequest(user_id="thierry")],
    hide_history_before=cutoff,
)
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    addMembers: [new Models\ChannelMemberRequest(userID: "thierry")],
    hideHistoryBefore: new \DateTime("-7 days"),
));
```

</codetabs-item>

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

```csharp
var cutoff = DateTime.UtcNow.AddDays(-7); // Last 7 days
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        AddMembers = new List<ChannelMemberRequest>
        {
            new ChannelMemberRequest { UserID = "thierry" }
        },
        HideHistoryBefore = cutoff
    });
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

cutoff = (DateTime.now - 7).iso8601 # Last 7 days
client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  add_members: [
    Models::ChannelMemberRequest.new(user_id: "thierry"),
  ],
  hide_history_before: cutoff,
))
```

</codetabs-item>

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

```java
// Backend SDK
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -7);
Date cutoff = calendar.getTime();

chat.updateChannel("channel-type", "channel-id", UpdateChannelRequest.builder()
    .addMembers(List.of(ChannelMemberRequest.builder().userID("thierry").build()))
    .hideHistoryBefore(cutoff)
    .build()).execute();
```

</codetabs-item>

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

```swift
let cutoff = Calendar.current.date(byAdding: .day, value: -7, to: Date())
channelController.addMembers(
  userIds: ["thierry"],
  hideHistoryBefore: cutoff
) { error in
  // …
}
```

</codetabs-item>

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

```dart
final cutoff = DateTime.now().subtract(Duration(days: 7)); // Last 7 days

await channel.addMembers(
  ["thierry"],
  hideHistoryBefore: cutoff,
);
```

</codetabs-item>

</codetabs>

## System Message Parameter

You can optionally include a message object when adding or removing members that client-side SDKs will use to display a system message. This works for both adding and removing members.

<codetabs>

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

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

// Add members with a system message
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 a system message
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, you need to specify the sender user_id
await channel.addMembers(["tommaso"], {
  text: "Tommaso joined the channel.",
  user_id: "tommaso",
});
```

</codetabs-item>

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

```go
channel.Update(ctx, &getstream.UpdateChannelRequest{
	AddMembers: []getstream.ChannelMemberRequest{{UserID: "tommaso"}},
	Message: &getstream.MessageRequest{
		Text:   getstream.PtrTo("Tommaso joined the channel."),
		UserID: getstream.PtrTo("tommaso"),
	},
})
```

</codetabs-item>

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

```python
from getstream.models import ChannelMemberRequest, MessageRequest

channel.update(
    add_members=[
        ChannelMemberRequest(user_id="tommaso"),
        ChannelMemberRequest(user_id="josh"),
    ],
    message=MessageRequest(
        text="Tommaso joined the channel.",
        user_id="tommaso",
    ),
)
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    addMembers: [new Models\ChannelMemberRequest(userID: "tommaso")],
    message: new Models\MessageRequest(
        text: "Tommaso joined the channel.",
        userID: "tommaso",
    ),
));
```

</codetabs-item>

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

```csharp
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        AddMembers = new List<ChannelMemberRequest>
        {
            new ChannelMemberRequest { UserID = "tommaso" }
        },
        Message = new MessageRequest
        {
            Text = "Tommaso joined the channel",
            UserID = "tommaso"
        }
    });
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  add_members: [
    Models::ChannelMemberRequest.new(user_id: "tommaso"),
    Models::ChannelMemberRequest.new(user_id: "josh"),
  ],
  message: Models::MessageRequest.new(
    text: "Tommaso joined the channel.",
    user_id: "tommaso",
  ),
))
```

</codetabs-item>

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

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

// Backend SDK
chat.updateChannel("messaging", "general", UpdateChannelRequest.builder()
    .addMembers(List.of(
        ChannelMemberRequest.builder().userID("thierry").build(),
        ChannelMemberRequest.builder().userID("josh").build()))
    .message(MessageRequest.builder()
        .text("Thierry and Josh were added to this channel")
        .build())
    .build()).execute();
```

</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>

## Adding and Removing Moderators

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.

### Add Moderators

<codetabs>

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

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

</codetabs-item>

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

```python
channel.update(add_moderators=["thierry", "josh"])
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  add_moderators: ["thierry", "josh"],
))
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    addModerators: ["thierry", "jenny"],
));
```

</codetabs-item>

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

```java
// Backend SDK
chat.updateChannel("channel-type", "channel-id", UpdateChannelRequest.builder()
    .addModerators(List.of("thierry", "josh"))
    .build()).execute();
```

</codetabs-item>

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

```csharp
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        AddModerators = new List<string> { "thierry", "josh" }
    });
```

</codetabs-item>

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

```go
channel.Update(ctx, &getstream.UpdateChannelRequest{
	AddModerators: []string{"thierry", "josh"},
})
```

</codetabs-item>

</codetabs>

### Remove Moderators

<codetabs>

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

```js
await channel.demoteModerators(["tommaso"]);
```

</codetabs-item>

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

```python
channel.update(demote_moderators=["tommaso"])
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

client.chat.update_channel("messaging", "channel-id", Models::UpdateChannelRequest.new(
  demote_moderators: ["tommaso"],
))
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

$client->updateChannel("messaging", "channel-id", new Models\UpdateChannelRequest(
    demoteModerators: ["thierry", "jenny"],
));
```

</codetabs-item>

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

```java
// Backend SDK
chat.updateChannel("channel-type", "channel-id", UpdateChannelRequest.builder()
    .demoteModerators(List.of("tommaso"))
    .build()).execute();
```

</codetabs-item>

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

```csharp
await chat.UpdateChannelAsync("messaging", channelId,
    new UpdateChannelRequest
    {
        DemoteModerators = new List<string> { "tommaso" }
    });
```

</codetabs-item>

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

```go
channel.Update(ctx, &getstream.UpdateChannelRequest{
	DemoteModerators: []string{"tommaso"},
})
```

</codetabs-item>

</codetabs>

<admonition type="info">

These operations can only be performed server-side, and a maximum of 100 moderators can be added or removed at once.

</admonition>

## Member Custom Data

Custom data can be added at the channel member level. This is useful for storing member-specific information that is separate from user-level data. Ensure custom data does not exceed 5KB.

### Adding Custom Data

<codetabs>

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

```js
// Add custom data while creating the channel
const channel = client.channel("messaging", randomID, {
  members: [
    { user_id: "userid1", key1: "value1" },
    { user_id: "userid2", key1: "value1" },
    { user_id: "userid3", key2: "value2" },
  ],
});

// Add custom data with addMembers method
await channel.addMembers([{ user_id: "userid1", key1: "value1" }]);
```

</codetabs-item>

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

```swift
channelController.addMembers([
	MemberInfo(userId: "userid1", extraData: ["key1": .string("value1")]),
	MemberInfo(userId: "userid2", extraData: ["key2": .string("value2")]),
	MemberInfo(userId: "userid3", extraData: ["key3": .string("value3")])
])
```

</codetabs-item>

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

```kotlin
// Add custom data while creating the channel
val params = CreateChannelParams(
  members = listOf(
    MemberData(userId = "userid1", extraData = mapOf("key1" to "value1")),
    MemberData(userId = "userid2", extraData = mapOf("key2" to "value2")),
    MemberData(userId = "userid3", extraData = mapOf("key3" to "value3")),
  ),
  extraData = emptyMap(),
)
channelClient.create(params).enqueue()

// Add custom data with addMembers method
val params = AddMembersParams(
  members = listOf(
    MemberData(userId = "userid1", extraData = mapOf("key1" to "value1")),
  ),
)
channelClient.addMembers(params).enqueue()
```

</codetabs-item>

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

```csharp
// Add a member first
await chat.UpdateChannelAsync("messaging", "my-channel-id",
    new UpdateChannelRequest
    {
        AddMembers = new List<ChannelMemberRequest>
        {
            new ChannelMemberRequest { UserID = "user-2" }
        }
    });

// Set custom data on the member
await chat.UpdateMemberPartialAsync("messaging", "my-channel-id",
    new UpdateMemberPartialRequest
    {
        Set = new Dictionary<string, object>
        {
            ["hat"] = "blue" // Channel member custom data is separate from user custom data
        }
    });
```

</codetabs-item>

</codetabs>

### Updating Member Data

Channel members can be partially updated. Only custom data and channel roles are eligible for modification. You can set or unset fields, either separately or in the same call.

<codetabs>

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

```js
// Set some fields
await channel.updateMemberPartial(
  {
    set: {
      key1: "new value 1",
      key2: "new value 2",
      channel_role: "channel_moderator",
    },
  },
  { userId: "jane" },
);

// Unset some fields
await channel.updateMemberPartial(
  {
    unset: ["key1", "key2"],
  },
  { userId: "jane" },
);

// Set and unset in the same call
await channel.updateMemberPartial(
  {
    set: {
      key1: "new value 1",
      key2: "new value 2",
    },
    unset: ["key3"],
  },
  { userId: "jane" },
);
```

</codetabs-item>

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

```swift
// Set some fields
let memberController = ChatClient.shared.memberController(
	userId: someUserId,
	in: someChannelId
)
memberController.partialUpdate(extraData: [
	"key1": .string("value1"),
	"key2": .string("value2")
])

// Unset some fields
memberController.partialUpdate(extraData: nil, unsetProperties: ["key1", "key2"])

// Set and unset in the same call
memberController.partialUpdate(
	extraData: [
		"key1": .string("value1"),
		"key2": .string("value2"),
	],
	unsetProperties: ["key3"]
)
```

</codetabs-item>

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

```go
channel := client.Chat().Channel("messaging", "general")

// Set some fields
channel.UpdateMemberPartial(ctx, &getstream.UpdateMemberPartialRequest{
	UserID: getstream.PtrTo("userid1"),
	Set:    map[string]any{"color": "red"},
})

// Unset some fields
channel.UpdateMemberPartial(ctx, &getstream.UpdateMemberPartialRequest{
	UserID: getstream.PtrTo("userid1"),
	Unset:  []string{"age"},
})

// Set and unset in the same call
channel.UpdateMemberPartial(ctx, &getstream.UpdateMemberPartialRequest{
	UserID: getstream.PtrTo("userid1"),
	Set:    map[string]any{"color": "red"},
	Unset:  []string{"age"},
})
```

</codetabs-item>

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

```php
use GetStream\ChatClient;
use GetStream\GeneratedModels as Models;

// Set some fields
$client->updateMemberPartial("messaging", "channel-id", "amy", new Models\UpdateMemberPartialRequest(
    set: (object)["hat" => "blue"],
));

// Unset some fields
$client->updateMemberPartial("messaging", "channel-id", "amy", new Models\UpdateMemberPartialRequest(
    unset: ["hat"],
));

// Set and unset in the same call
$client->updateMemberPartial("messaging", "channel-id", "amy", new Models\UpdateMemberPartialRequest(
    set: (object)["hat" => "blue"],
    unset: ["hat"],
));
```

</codetabs-item>

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

```python
user_id = "amy"

# Set some fields
response = channel.update_member_partial(user_id=user_id, set={"hat": "blue"})

# Unset some fields
response = channel.update_member_partial(user_id=user_id, unset=["hat"])

# Set and unset in the same call
response = channel.update_member_partial(user_id=user_id, set={"color": "red"}, unset=["hat"])
```

</codetabs-item>

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

```ruby
require 'getstream_ruby'
Models = GetStream::Generated::Models

user_id = "amy"

# Set some fields
client.chat.update_member_partial("messaging", "channel-id", Models::UpdateMemberPartialRequest.new(
  set: { 'color' => 'red' }
), user_id)

# Unset some fields
client.chat.update_member_partial("messaging", "channel-id", Models::UpdateMemberPartialRequest.new(
  unset: ['hat']
), user_id)

# Set and unset in the same call
client.chat.update_member_partial("messaging", "channel-id", Models::UpdateMemberPartialRequest.new(
  set: { 'color' => 'red' },
  unset: ['hat']
), user_id)
```

</codetabs-item>

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

```java
// Set some fields
chat.updateMemberPartial(channel.getType(), channel.getId(), UpdateMemberPartialRequest.builder()
    .UserID("user-1")
    .set(Map.of("custom_key", "custom_value", "channel_role", "channel_moderator"))
    .build()).execute();

// Unset some fields
chat.updateMemberPartial(channel.getType(), channel.getId(), UpdateMemberPartialRequest.builder()
    .UserID("user-1")
    .unset(List.of("custom_key"))
    .build()).execute();

// Set and unset in the same call
chat.updateMemberPartial(channel.getType(), channel.getId(), UpdateMemberPartialRequest.builder()
    .UserID("user-1")
    .set(Map.of("color", "red"))
    .unset(List.of("age"))
    .build()).execute();
```

</codetabs-item>

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

```csharp
// Set some fields
// Note: user_id is passed as a query parameter
await client.MakeRequestAsync<UpdateMemberPartialRequest, UpdateMemberPartialResponse>(
    "PATCH",
    "/api/v2/chat/channels/{type}/{id}/member",
    new Dictionary<string, string> { ["user_id"] = "user-2" },
    new UpdateMemberPartialRequest
    {
        Set = new Dictionary<string, object>
        {
            ["hat"] = "blue",
            ["score"] = 1000
        }
    },
    new Dictionary<string, string> { ["type"] = "messaging", ["id"] = "my-channel-id" });

// Unset some fields
await client.MakeRequestAsync<UpdateMemberPartialRequest, UpdateMemberPartialResponse>(
    "PATCH",
    "/api/v2/chat/channels/{type}/{id}/member",
    new Dictionary<string, string> { ["user_id"] = "user-2" },
    new UpdateMemberPartialRequest
    {
        Unset = new List<string> { "hat", "score" }
    },
    new Dictionary<string, string> { ["type"] = "messaging", ["id"] = "my-channel-id" });

// Set and unset in a single request
await client.MakeRequestAsync<UpdateMemberPartialRequest, UpdateMemberPartialResponse>(
    "PATCH",
    "/api/v2/chat/channels/{type}/{id}/member",
    new Dictionary<string, string> { ["user_id"] = "user-2" },
    new UpdateMemberPartialRequest
    {
        Set = new Dictionary<string, object> { ["hat"] = "blue" },
        Unset = new List<string> { "score" }
    },
    new Dictionary<string, string> { ["type"] = "messaging", ["id"] = "my-channel-id" });
```

</codetabs-item>

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

```kotlin
// Set some fields
channelClient.partialUpdateMember(
  userId = "userid1",
  set = mapOf(
    "key1" to "new value 1",
    "key2" to "new value 2",
  ),
).enqueue()

// Unset some fields
channelClient.partialUpdateMember(
  userId = "userid1",
  unset = listOf("key1", "key2"),
).enqueue()

// Set and unset in the same call
channelClient.partialUpdateMember(
  userId = "userid1",
  set = mapOf(
    "key1" to "new value 1",
    "key2" to "new value 2",
  ),
  unset = listOf("key3"),
).enqueue()
```

</codetabs-item>

</codetabs>


---

This page was last updated at 2026-03-13T13:16:54.238Z.

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