const newUser: UserRequest = {
  id: 'user-id',
  role: 'user',
  custom: {
    color: 'red',
  },
  name: 'This is a test user',
  image: 'link/to/profile/image',
};
await client.upsertUsers([newUser]);User management
The operations performed on users, such as updating and deleting, have an effect on all products (chat, feeds and video).
Creating users
When creating users, there are a few important things to keep in mind:
- The 
idfield is mandatory, in most cases you want this to be the same ID you use on your database. - The 
rolefield is optional, by default it is set touserbut you can specify any existing role. - Custom data can be added to users in the 
customfield. nameandimageare optional and handled by all SDKs automatically to render users.
users := map[string]getstream.UserRequest{
    "user1": {
        ID:   "user1",
        Name: getstream.PtrTo("Test User 1"),
        Role: getstream.PtrTo("user"),
    },
    "user2": {
        ID:   "user2",
        Name: getstream.PtrTo("Test User 2"),
        Role: getstream.PtrTo("user"),
    },
}
request := &getstream.UpdateUsersRequest{
    Users: users,
}
response, err := client.UpdateUsers(context.Background(), request)
if err != nil {
    log.Fatal("Error updating users:", err)
}
log.Printf("Users updated successfully: %+v\n", response)Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();use GetStream\ClientBuilder;
use GetStream\GeneratedModels;
$client = (new ClientBuilder())
    ->apiKey($apiKey)
    ->apiSecret($apiSecret)
    ->build();
$response = $client->updateUsers(new GeneratedModels\UpdateUsersRequest(
    users: [
        'user-id-1' => [
            'id' => 'user-id-1',
            'name' => 'Test User 1',
            'role' => 'user',
            'custom' => (object)[
                'color' => 'red'
            ]
        ],
        'user-id-2' => [
            'id' => 'user-id-2',
            'name' => 'Test User 2',
            'role' => 'user'
        ]
    ]
));var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)# Create/update users in batch
update_request = GetStream::Generated::Models::UpdateUsersRequest.new(
  users: {
    'user1' => {
      'id' => 'user1',
      'name' => 'Test User 1',
      'role' => 'user',
    },
    'user2' => {
      'id' => 'user2',
      'name' => 'Test User 2',
      'role' => 'user',
    },
  },
)
response = client.common.update_users(update_request)Updating users
You can update users in two ways:
- Replace updates: replace the entire user object with the one provided to the API call
 - Partial update: choose which fields you want to change
 
const user: UserRequest = {
  id: 'userid',
  role: 'user',
  custom: {
    color: 'blue',
  },
  name: 'This is a test user',
  image: 'link/to/profile/image',
};
client.upsertUsers([user]);
// or
client.updateUsersPartial({
  users: [
    {
      id: user.id,
      set: {
        'new-field': 'value',
      },
      unset: ['name'],
    },
  ],
});// Example 1: Upsert users
user := getstream.UserRequest{
    ID:   "userid",
    Role: getstream.PtrTo("user"),
    Custom: map[string]any{
        "color": "blue",
    },
    Name:  getstream.PtrTo("This is a test user"),
    Image: getstream.PtrTo("link/to/profile/image"),
}
upsertRequest := &getstream.UpdateUsersRequest{
    Users: map[string]getstream.UserRequest{
        user.ID: user,
    },
}
upsertResponse, err := client.UpdateUsers(context.Background(), upsertRequest)
if err != nil {
    log.Fatal("Error upserting users:", err)
}
log.Printf("Users upserted successfully: %+v\n", upsertResponse)
// Example 2: Partial update users
partialUpdateRequest := &getstream.UpdateUsersPartialRequest{
    Users: []getstream.UpdateUserPartialRequest{
        {
            ID: user.ID,
            Set: map[string]any{
                "new-field": "value",
            },
            Unset: []string{"name"},
        },
    },
}
partialResponse, err := client.UpdateUsersPartial(context.Background(), partialUpdateRequest)
if err != nil {
    log.Fatal("Error partially updating users:", err)
}
log.Printf("Users partially updated successfully: %+v\n", partialResponse)Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();// Example 1: Upsert users (replace update)
$client->updateUsers(new GeneratedModels\UpdateUsersRequest(
    users: [
        'userid' => [
            'id' => 'userid',
            'name' => 'This is a test user',
            'role' => 'user',
            'custom' => (object)[
                'color' => 'blue'
            ],
            'image' => 'link/to/profile/image'
        ]
    ]
));
// Example 2: Partial update users
$client->updateUsersPartial(new GeneratedModels\UpdateUsersPartialRequest(
    users: [
        [
            'id' => 'userid',
            'set' => (object)[
                'new-field' => 'value'
            ],
            'unset' => ['name']
        ]
    ]
));var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)# Partially update user
partial_request = GetStream::Generated::Models::UpdateUsersPartialRequest.new(
  users: [
    {
      'id' => 'userid',
      'set' => {
        'name' => 'Updated Name',
      },
    },
  ],
)
response = client.common.update_users_partial(partial_request)Anonymous users
Anonymous users are users that are not authenticated. It’s common to use this for watching a livestream or similar where you aren’t authenticated. Anonymous users can be connected using client-side SDKs. Anonymous users are not counted toward your MAU.
Guest users
Guest users are temporary user accounts. You can use it to temporarily give someone a name and image when joining a call. Guest users can be created client-side. Guest users are counted towards your MAU usage.
Deactivating and deleting users
Depending on your use-case, you can choose to delete users or de-activating them. There are some differences between these two approach.
Deactivating users:
- the user will not be allowed to perform API requests / connect
 - user data is retained on Stream’s side and returned from API
 - deactivated users can be re-activated
 
Deleting users:
- the user will no longer be able to perform API requests / connect
 - the user is deleted and by default not returned from API
 - all data from the user is marked as deleted
 - by default the data is retained and “soft” deleted, you can optionally request hard deletion
 - deletion is not reversible
 
Note: Both deletion and deactivation are performed asynchronously by Stream API. A task ID is returned and you can use that to check the status of its processing.
Deactivating users
client.deactivateUser({
  user_id: '<id>',
});
// reactivate
client.reactivateUsers({
  user_ids: ['<id>'],
});
// deactivating users in bulk is performed asynchronously
const deactivateResponse = client.deactivateUsers({
  user_ids: ['<id1>', '<id2>'...],
});// Deactivating a single user
_, err = client.DeactivateUser(context.Background(), "user1", &getstream.DeactivateUserRequest{})
if err != nil {
    log.Fatal("Error deactivating user:", err)
}
log.Printf("User deactivated successfully")
// Deactivating users in bulk is performed asynchronously
_, err = client.DeactivateUsers(context.Background(), &getstream.DeactivateUsersRequest{
    UserIds: []string{"user2"},
})
if err != nil {
    log.Fatal("Error deactivating users:", err)
}
log.Printf("Users deactivated successfully")
// Reactivate users
reactivateRequest := &getstream.ReactivateUsersRequest{
    UserIds: []string{"user1", "user2"},
}
_, err = client.ReactivateUsers(context.Background(), reactivateRequest)
if err != nil {
    log.Fatal("Error reactivating users:", err)
}
log.Printf("Users reactivated successfully")Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();// Deactivating a single user
$client->deactivateUser(
    'user1',
    new GeneratedModels\DeactivateUserRequest()
);
// Deactivating users in bulk is performed asynchronously
$response = $client->deactivateUsers(
    new GeneratedModels\DeactivateUsersRequest(
        userIds: ['user1', 'user2']
    )
);
// Reactivate users
$client->reactivateUsers(
    new GeneratedModels\ReactivateUsersRequest(
        userIds: ['user1', 'user2']
    )
);var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)Deactivating users in bulk can take some time, this is how you can check the progress:
// Example of monitoring the status of an async task
// The logic is same for all async tasks
const response = await client.exportUsers({
  user_ids: ["<user id1>", "<user id1>"],
});
// you need to poll this endpoint
const taskResponse = await client.getTask({ id: response.task_id });
console.log(taskResponse.status === "completed");// Example of monitoring the status of an async task
// The logic is same for all async tasks
response, err := client.ExportUsers(context.Background(), &getstream.ExportUsersRequest{
	UserIds: []string{"<user id1>", "<user id2>"},
})
if err != nil {
    log.Fatal(err)
}
// you need to poll this endpoint
taskResponse, err := client.GetTask(context.Background(), response.Data.TaskID, &getstream.GetTaskRequest{})
if err != nil {
    log.Fatal(err)
}
fmt.Println(taskResponse.Data.Status == "completed")Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();// Example of monitoring the status of an async task
// The logic is same for all async tasks
$response = $client->exportUsers(
    new GeneratedModels\ExportUsersRequest(
        userIds: ['<user id1>', '<user id2>']
    )
);
$responseData = $response->getData();
$taskId = $responseData->taskID;
// you need to poll this endpoint
$taskResponse = $client->getTask($taskId);
$taskData = $taskResponse->getData();
echo $taskData->status === 'completed';var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)Deleting users
client.deleteUsers({ user_ids: ["<id>"] });
//restore
client.restoreUsers({ user_ids: ["<id>"] });// Delete users
deleteRequest := &getstream.DeleteUsersRequest{
    UserIds: []string{"<id>"},
}
_, err = client.DeleteUsers(context.Background(), deleteRequest)
// Restore users
restoreRequest := &getstream.RestoreUsersRequest{
    UserIds: []string{"<id>"},
}
_, err = client.RestoreUsers(context.Background(), restoreRequest)Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();// Delete users (soft delete by default)
$client->deleteUsers(
    new GeneratedModels\DeleteUsersRequest(
        userIds: ['<id>']
    )
);
// Delete users with options (hard delete)
$client->deleteUsers(
    new GeneratedModels\DeleteUsersRequest(
        userIds: ['<id>'],
        user: 'hard',
        messages: 'hard',
        conversations: 'hard',
        newChannelOwnerID: 'new-owner-id'
    )
);
// Restore users
$client->restoreUsers(
    new GeneratedModels\RestoreUsersRequest(
        userIds: ['<id>']
    )
);var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)# Delete users in batch
delete_request = GetStream::Generated::Models::DeleteUsersRequest.new(
  user_ids: ['user1', 'user2'],
  user: 'hard',
)
response = client.common.delete_users(delete_request)The delete users endpoints supports the following parameters to control which data needs to be deleted and how. By default users and their data are soft-deleted.
| Name | Type | Description | Optional | 
|---|---|---|---|
user | Enum (soft, pruning, hard) | - Soft: marks user as deleted and retains all user data.  - Pruning: marks user as deleted and nullifies user information. - Hard: deletes user completely - this requires hard option for messages and conversation as well.  | Yes | 
conversations | Enum (soft, hard) | - Soft: marks all conversation channels as deleted (same effect as Delete Channels with ‘hard’ option disabled).  - Hard: deletes channel and all its data completely including messages (same effect as Delete Channels with ‘hard’ option enabled).  | Yes | 
messages | Enum (soft, pruning, hard) | - Soft: marks all user messages as deleted without removing any related message data.  - Pruning: marks all user messages as deleted, nullifies message information and removes some message data such as reactions and flags. - Hard: deletes messages completely with all related information.  | Yes | 
new_channel_owner_id | string | Channels owned by hard-deleted users will be transferred to this userID. If you doesn’t provide a value, the channel owner will have a system generated ID like delete-user-8219f6578a7395g | Yes | 
calls | Enum (soft, hard) | - Soft: marks calls and related data as deleted.  - Hard: deletes calls and related data completely Note that this applies only to 1:1 calls, not group calls  | Yes | 
Deleting users in bulk can take some time, this is how you can check the progress:
// Example of monitoring the status of an async task
// The logic is same for all async tasks
const response = await client.exportUsers({
  user_ids: ["<user id1>", "<user id1>"],
});
// you need to poll this endpoint
const taskResponse = await client.getTask({ id: response.task_id });
console.log(taskResponse.status === "completed");// Example of monitoring the status of an async task
// The logic is same for all async tasks
response, err := client.ExportUsers(context.Background(), &getstream.ExportUsersRequest{
	UserIds: []string{"<user id1>", "<user id2>"},
})
if err != nil {
    log.Fatal(err)
}
// you need to poll this endpoint
taskResponse, err := client.GetTask(context.Background(), response.Data.TaskID, &getstream.GetTaskRequest{})
if err != nil {
    log.Fatal(err)
}
fmt.Println(taskResponse.Data.Status == "completed")Map<String, UserRequest> usersMap = new HashMap<>();
usersMap.put(
    testUserId,
    UserRequest.builder().id(testUserId).name("Test User 1").role("user").build());
usersMap.put(
    testUserId2,
    UserRequest.builder().id(testUserId2).name("Test User 2").role("user").build());
UpdateUsersRequest updateUsersRequest = UpdateUsersRequest.builder().users(usersMap).build();
client.updateUsers(updateUsersRequest).execute();// Example of monitoring the status of an async task
// The logic is same for all async tasks
$response = $client->exportUsers(
    new GeneratedModels\ExportUsersRequest(
        userIds: ['<user id1>', '<user id2>']
    )
);
$responseData = $response->getData();
$taskId = $responseData->taskID;
// you need to poll this endpoint
$taskResponse = $client->getTask($taskId);
$taskData = $taskResponse->getData();
echo $taskData->status === 'completed';var updateUsersRequest = new UpdateUsersRequest
{
    Users = new Dictionary<string, UserRequest>
    {
        [_testUserId] = new UserRequest
        {
            ID = _testUserId,
            Name = "Test User 1",
            Role = "user"
        },
        [_testUserId2] = new UserRequest
        {
            ID = _testUserId2,
            Name = "Test User 2",
            Role = "user"
        },
        [_testUserId3] = new UserRequest
        {
            ID = _testUserId3,
            Name = "Test User 3",
            Role = "user"
        }
    }
};
var userResponse = await _client.UpdateUsersAsync(updateUsersRequest);users = {
    self.test_user_id: UserRequest(
        id=self.test_user_id, name="Test User 1", role="user"
    ),
    self.test_user_id_2: UserRequest(
        id=self.test_user_id_2, name="Test User 2", role="user"
    ),
}
response = self.client.update_users(users=users)