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
id
field is mandatory, in most cases you want this to be the same ID you use on your database. - The
role
field is optional, by default it is set touser
but you can specify any existing role. - Custom data can be added to users in the
custom
field. name
andimage
are optional and handled by all SDKs automatically to render users.
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
users := map[string]interface{}{
"user1": map[string]interface{}{
"id": "user1",
"name": "Test User 1",
"role": "user",
},
"user2": map[string]interface{}{
"id": "user2",
"name": "Test User 2",
"role": "user",
},
}
request := &getstream.UpdateUsersRequest{
Users: users,
}
_, err = client.UpdateUsers(context.Background(), request)
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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)
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'],
},
],
});
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
users := map[string]interface{}{
"user1": map[string]interface{}{
"id": "user1",
"name": "Test User 1",
"role": "user",
},
"user2": map[string]interface{}{
"id": "user2",
"name": "Test User 2",
"role": "user",
},
}
request := &getstream.UpdateUsersRequest{
Users: users,
}
_, err = client.UpdateUsers(context.Background(), request)
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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)
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>'...],
});
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
// Deactivating users in bulk is performed asynchronously
request := &getstream.DeactivateUsersRequest{
UserIds: []string{"<id1>", "<id2>"},
}
_, err = client.DeactivateUsers(context.Background(), request)
// Reactivate users
reactivateRequest := &getstream.ReactivateUsersRequest{
UserIds: []string{"<id>"},
}
_, err = client.ReactivateUsers(context.Background(), reactivateRequest)
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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)
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");
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
// 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.TaskId, &getstream.GetTaskRequest{})
if err != nil {
log.Fatal(err)
}
fmt.Println(taskResponse.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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)
Deleting users
client.deleteUsers({ user_ids: ["<id>"] });
//restore
client.restoreUsers({ user_ids: ["<id>"] });
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
// 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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)
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");
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
// 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.TaskId, &getstream.GetTaskRequest{})
if err != nil {
log.Fatal(err)
}
fmt.Println(taskResponse.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();
$response = $this->client->updateUsers(new GeneratedModels\UpdateUsersRequest(
users: [
$this->testUserId => [
'id' => $this->testUserId,
'name' => 'Test User 1',
'role' => 'user'
],
$this->testUserId2 => [
'id' => $this->testUserId2,
'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)