# Updating a Channel

There are two ways to update a channel with the Stream API: partial updates and full updates. A partial update preserves existing custom key–value data, while a full update replaces the entire channel object and removes any fields not included in the request.

## Partial Update

A partial update lets you set or unset specific fields without affecting the rest of the channel’s custom data — essentially a patch-style update.

<codetabs>

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

```kotlin
// Here's a channel with some custom field data that might be useful
val channelClient = client.channel(channelType = "messaging", channelId = "general")

channelClient.create(
  memberIds = listOf("thierry", "tomasso"),
  extraData = mapOf(
    "source" to "user",
    "source_detail" to mapOf("user_id" to 123),
    "channel_detail" to mapOf(
      "topic" to "Plants and Animals",
      "rating" to "pg"
    )
  )
).execute()

// let's change the source of this channel
channelClient.updatePartial(set = mapOf("source" to "system")).execute()

// since it's system generated we no longer need source_detail
channelClient.updatePartial(unset = listOf("source_detail")).execute()

// and finally update one of the nested fields in the channel_detail
channelClient.updatePartial(set = mapOf("channel_detail.topic" to "Nature")).execute()

// and maybe we decide we no longer need a rating
channelClient.updatePartial(unset = listOf("channel_detail.rating")).execute()
```

</codetabs-item>

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

```js
// Here's a channel with some custom field data that might be useful
const channel = client.channel(type, id, {
  source: "user",
  source_detail: { user_id: 123 },
  channel_detail: { topic: "Plants and Animals", rating: "pg" },
});

// let's change the source of this channel
await channel.updatePartial({ set: { source: "system" } });

// since it's system generated we no longer need source_detail
await channel.updatePartial({ unset: ["source_detail"] });

// and finally update one of the nested fields in the channel_detail
await channel.updatePartial({ set: { "channel_detail.topic": "Nature" } });

// and maybe we decide we no longer need a rating
await channel.updatePartial({ unset: ["channel_detail.rating"] });
```

</codetabs-item>

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

```dart
// Here's a channel with some custom field data that might be useful
var channel = client.channel(type, id: id, extraData: {
 "source": "user",
 "source_detail" :{ "user_id": 123 },
 "channel_detail" :{ "topic": "Plants and Animals", "rating": "pg" }
});

// let's change the source of this channel
await channel.updatePartial(set: { "source": "system" });

// since it's system generated we no longer need source_detail
await channel.updatePartial(unset: ["source_detail"]);

// and finally update one of the nested fields in the channel_detail
await channel.updatePartial(set: { "channel_detail.topic": "Nature" });

// and maybe we decide we no longer need a rating
await channel.updatePartial(unset: ["channel_detail.rating"]);
```

</codetabs-item>

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

```python
# Here's a channel with some custom field data that might be useful
channel = client.channel(type, id , {
 "source": "user",
 "source_detail":{ "user_id": 123 },
 "channel_detail":{ "topic": "Plants and Animals", "rating": "pg" }
})

# let's change the source of this channel
channel.update_partial(to_set={ "source": "system" });

# since it's system generated we no longer need source_detail
channel.update_partial(to_unset=["source_detail"]);

# and finally update one of the nested fields in the channel_detail
channel.update_partial(to_set={ "channel_detail.topic": "Nature" });

# and maybe we decide we no longer need a rating
channel.update_partial(to_unset=["channel_detail.rating"]);
```

</codetabs-item>

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

```php
// Here's a channel with some custom field data that might be useful
$channel = $client->Channel('messaging', 'thierry-jenny',
['source'=>'user','source_detail'=>['user_id'=>123],
'channel_detail'=>['topic'=>'Plants and Animals', 'rating'=> 'pg'] ]);

// let's change the source of this channel
$response = $channel->updatePartial(['source' => 'system']);

// since it's system generated we no longer need source_detail
$response = $channel->updatePartial(null,['source_detail']);

// and finally update one of the nested fields in the channel_detail
$response = $channel->updatePartial(['source_detail'=> ['topic' => 'Nature']]);

// and maybe we decide we no longer need a rating
$response = $channel->updatePartial(null,['source_detail'=>'topic']);
```

</codetabs-item>

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

```csharp
// Create a channel with some custom data
var req = new ChannelGetRequest
{
  Data = new ChannelRequest
  {
    CreatedBy = new UserRequest { Id = createdByUserId },
  },
};

req.Data.SetData("source", "user");
req.Data.SetData("source_detail", new Dictionary<string, object> { { "user_id", 123} });
req.Data.SetData("channel_detail", new Dictionary<string, object>
{
  { "topic", "Plants and Animals"},
  { "rating", "pg" }
});
var channelResp = await channelClient.GetOrCreateAsync("messaging", "general", req);

// Remove channel detail rating, and set a new source
var req = new PartialUpdateChannelRequest
{

  Unset = new List<string> { "channel_detail.rating" },
  Set = new Dictionary<string, object> { { "source", "system" } }
};
await channelClient.PartialUpdateAsync(channelResp.Channel.Type, channelResp.Channel.Id, req);
```

</codetabs-item>

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

```cpp
// Create a channel with some custom field data that might be useful
FChannelProperties Props = FChannelProperties{Type, Id};

// Set extra data using dynamic JSON. You'd more likely want to use statically typed structs.
Props.ExtraData.SetString(TEXT("source"), TEXT("user"));
const TSharedRef<FJsonObject> SourceDetail = MakeShared<FJsonObject>();
SourceDetail->SetNumberField(TEXT("user_id"), 123);
Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(SourceDetail));
const TSharedRef<FJsonObject> ChannelDetail = MakeShared<FJsonObject>();
ChannelDetail->SetStringField(TEXT("topic"), TEXT("Plants and Animals"));
ChannelDetail->SetStringField(TEXT("rating"), TEXT("pg"));
Props.ExtraData.SetJsonValue(TEXT("source_detail"), MakeShared<FJsonValueObject>(ChannelDetail));
Client->CreateChannel(
  Props,
  [](UChatChannel* Channel)
  {
    // let's change the source of this channel
    const TSharedRef<FJsonObject> NewSource = MakeShared<FJsonObject>();
    NewSource->SetStringField(TEXT("source"), TEXT("system"));
    Channel->PartialUpdate(NewSource);

    // since it's system generated we no longer need source_detail
    Channel->PartialUpdate({}, {TEXT("source_detail")});

    // and finally update one of the nested fields in the channel_detail
    const TSharedRef<FJsonObject> NewTopic = MakeShared<FJsonObject>();
    NewSource->SetStringField(TEXT("channel_detail.topic"), TEXT("Nature"));
    Channel->PartialUpdate(NewSource);

    // and maybe we decide we no longer need a rating
    Channel->PartialUpdate({}, {TEXT("channel_detail.rating")});
  });
```

</codetabs-item>

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

```go
resp, err := c.CreateChannel(ctx, "messaging", "general", "thierry", map[string]interface{}{
	"source": "user",
	"source_detail": map[string]interface{}{"user_id": "123"},
	"channel_detail": map[string]interface{}{"topic": "Plants and Animals", "rating": "pg"},
})

channel := resp.Channel

// let's change the source of this channel
channel.PartialUpdate(ctx, PartialUpdate{
	Set: map[string]interface{}{
		"source": "system",
	},
})

// since it's system generated we no longer need source_detail
channel.PartialUpdate(ctx, PartialUpdate{
	Unset: []string{"source_detail"},
})

// and finally update one of the nested fields in the channel_detail
channel.PartialUpdate(ctx, PartialUpdate{
	Set: map[string]interface{}{
		"channel_detail.topic": "Nature",
	},
})

// and maybe we decide we no longer need a rating
channel.PartialUpdate(ctx, PartialUpdate{
	Unset: []string{"channel_detail.rating"},
})
```

</codetabs-item>

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

```ruby
# require 'stream-chat'

# Here's a channel with some custom field data that might be useful
channel = client.channel(type, id , data: {
 "source" => "user",
 "source_detail" => { "user_id" => 123 },
 "channel_detail" => { "topic" => "Plants and Animals", "rating" => "pg" }
})

# let's change the source of this channel
channel.update_partial({ "source" => "system" });

# since it's system generated we no longer need source_detail
channel.update_partial(nil, ["source_detail"]);

# and finally update one of the nested fields in the channel_detail
channel.update_partial({ "channel_detail.topic" => "Nature" });

# and maybe we decide we no longer need a rating
channel.update_partial(nil, ["channel_detail.rating"]);
```

</codetabs-item>

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

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

  var setClanInfo = new ClanData
  {
    MaxMembers = 50,
    Name = "Wild Boards",
    Tags = new List<string>
    {
      "Competitive",
      "Legendary",
    }
  };

  var setFields = new Dictionary<string, object>();

  // Set custom values
  setFields.Add("frags", 5);
  // Set custom arrays
  setFields.Add("items", new[] { "sword", "shield" });
  // Set custom class objects
  setFields.Add("clan_info", setClanInfo);

  // Send data
  await channel.UpdatePartialAsync(setFields);

  // Data is now available via CustomData property
  var frags = channel.CustomData.Get<int>("frags");
  var items = channel.CustomData.Get<List<string>>("items");
  var clanInfo = channel.CustomData.Get<ClanData>("clan_info");
}

// Example class with data that you can assign as Channel custom data
private class ClanData
{
  public int MaxMembers;
  public string Name;
  public List<string> Tags;
}
```

</codetabs-item>

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

```java
// Android SDK

// Here's a channel with some custom field data that might be useful
ChannelClient channelClient = client.channel("messaging", "general");

List<String> members = Arrays.asList("thierry", "tommaso");

Map<String, String> channelDetail = new HashMap<>();
channelDetail.put("topic", "Plants and Animals");
channelDetail.put("rating", "pg");

Map<String, Integer> userId = new HashMap<>();
userId.put("user_id", 123);

Map<String, Object> extraData = new HashMap<>();
extraData.put("source", "user");
extraData.put("source_detail", userId);
extraData.put("channel_detail", channelDetail);

channelClient.create(members, extraData).execute();

// let's change the source of this channel
Map<String, Object> setField = Collections.singletonMap("source", "system");
channelClient.updatePartial(setField, emptyList()).execute();

// since it's system generated we no longer need source_detail
List<String> unsetField = Collections.singletonList("source_detail");
channelClient.updatePartial(emptyMap(), unsetField).execute();

// and finally update one of the nested fields in the channel_detail
Map<String, Object> setNestedField = Collections.singletonMap("channel_detail.topic", "Nature");
channelClient.updatePartial(setNestedField, emptyList()).execute();

// and maybe we decide we no longer need a rating
List<String> unsetNestedField = Collections.singletonList("channel_detail.rating");
channelClient.updatePartial(emptyMap(), unsetNestedField).execute();

// Backend SDK
Channel.partialUpdate("messaging", "general")
  .setValue("source", "system")
  .setValue("channel_detail.topic", "Nature")
  .user(user)
  .unsetValue("source_detail")
  .request()
  .getChannel();
```

</codetabs-item>

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

```swift
channelController.partialChannelUpdate(
    extraData: [
        "source": .string("user"),
        "source_detail": .dictionary(["user_id": .number(123)]),
        "channel_detail": .dictionary([
            "topic": .string("Plants and Animals"),
            "rating": .string("pg")
        ])
    ]
) { error in
    if let error {
        // handle error
    }
}

// let's change the source of this channel
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])

// let's change the source of this channel
channelController.partialChannelUpdate(extraData:["source": "system"])

// since it's system generated we no longer need source_detail
channelController.partialChannelUpdate(unsetProperties: ["source_detail"])

// and finally update one of the nested fields in the channel_detail
channelController.partialChannelUpdate(extraData:["channel_detail.topic": "Nature"])
```

</codetabs-item>

</codetabs>

## Full Update

The `update` function updates all of the channel data. **Any data that is present on the channel and not included in a full update will be deleted.**

<codetabs>

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

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

channelClient.update(
  message = Message(
    text = "Thierry changed the channel color to green"
  ),
  extraData = mapOf(
    "name" to "myspecialchannel",
    "color" to "green",
  ),
).enqueue { result ->
  if (result is Result.Success) {
    val channel = result.value
  } else {
    // Handle Result.Failure
  }
}
```

</codetabs-item>

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

```js
const update = await channel.update({
  name: "myspecialchannel",
  color: "green",
});
```

</codetabs-item>

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

```dart
await channel.update({
 "name": "myspecialchannel",
 "color": "green",
}, Message(text: "Thierry changed the channel color to green"));
```

</codetabs-item>

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

```php
$update = $channel->update(
	[
		'name'  => 'myspecialchannel',
		'color'	 => 'green'
	],
	[
		'text' => 'Thierry changed the channel color to green',
		'user_id' => 'thierry'
	]
);
```

</codetabs-item>

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

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

channelController.updateChannel(
    name: "My special channel",
    imageURL: nil,
    team: nil,
    extraData: [
        "name": .string("myspecialchannel"),
        "color": .string("green"),
    ]
) { error in
    if let error {
        // handle error
    }
}
```

</codetabs-item>

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

```python
channel.update(
  {
    "name": "myspecialchannel",
    "color": "green",
  },
)
```

</codetabs-item>

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

```cpp
FAdditionalFields Data;
Data.SetString(TEXT("name"), TEXT("myspecialchannel"));
Data.SetString(TEXT("color"), TEXT("green"));
Channel->Update(Data, Message);
```

</codetabs-item>

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

```csharp
var updatedChannel = new ChannelUpdateRequest { Data = new ChannelRequest() };
updatedChannel.Data.SetData("name", "myspecialchannel");
updatedChannel.Data.SetData("color", "green");

await channelClient.UpdateAsync(channel.Type, channel.Id, updatedChannel);
```

</codetabs-item>

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

```go
channel.Update(ctx, map[string]interface{}{"color": "green"},)
```

</codetabs-item>

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

```ruby
channel.update(
  {
    "name" => "myspecialchannel",
    "color" => "green",
  },
)
```

</codetabs-item>

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

```csharp
var updateRequest = new StreamUpdateOverwriteChannelRequest
{
  Name = "New name",
  CustomData = new StreamCustomDataRequest
  {
    {"my-custom-int", 12},
    {"my-custom-array", new string[]{"one", "two"}}
  }
};

// This request will have all channel data removed except what is being passed in the request
await channel.UpdateOverwriteAsync(updateRequest);

// You can also pass an instance of channel to the request constructor to have all of the date copied over
// This way you alter only the fields you wish to change
var updateRequest2 = new StreamUpdateOverwriteChannelRequest(channel)
{
  Name = "Brand new name"
};

// This will update only the name because all other data was copied over
await channel.UpdateOverwriteAsync(updateRequest2);
```

</codetabs-item>

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

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

Map<String, Object> channelData = new HashMap<>();
channelData.put("name", "myspecialchannel");
channelData.put("color", "green");
Message updateMessage = new Message();
updateMessage.setText("Thierry changed the channel color to green");

channelClient.update(updateMessage, channelData).enqueue(result -> {
  if (result.isSuccess()) {
    Channel channel = result.data();
  } else {
    // Handle result.error()
  }
 });


// Backend SDK
MessageRequestObject msg = MessageRequestObject
  .builder()
    .text("Thierry changed the channel color to green")
  .build();

Channel.update("messaging", "general")
  .message(msg)
  .data(ChannelRequestObject.builder()
   .additionalField("name", "myspecialchannel")
   .additionalField("color", "green")
   .build())
  .request();
```

</codetabs-item>

</codetabs>

### Request Params

| Name         | Type   | Description                                                                                                                                                                          | Optional |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| channel data | object | Object with the new channel information. One special field is "frozen". Setting this field to true will freeze the channel. Read more about freezing channels in "Freezing Channels" |          |
| text         | object | Message object allowing you to show a system message in the Channel that something changed.                                                                                          | Yes      |

<admonition type="info">

Updating a channel using these methods cannot be used to add or remove members. For this, you must use specific methods for adding/removing members, more information can be found [here](/chat/docs/<framework>/channel_members/).

</admonition>


---

This page was last updated at 2026-03-05T19:05:59.766Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/python/channel_update/](https://getstream.io/chat/docs/python/channel_update/).