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.
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Create/upsert a new user
response, err := client.UpsertUsers(ctx, &getstream.UpsertUsersRequest{
Users: []getstream.UserRequest{
{
ID: "user-id",
Role: getstream.PtrTo("user"),
Custom: map[string]interface{}{
"color": "red",
},
Name: getstream.PtrTo("This is a test user"),
Image: getstream.PtrTo("link/to/profile/image"),
},
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("User created successfully: %+v", response.Data.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'],
},
],
});
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Replace update: replace the entire user object
response, err := client.UpsertUsers(ctx, &getstream.UpsertUsersRequest{
Users: []getstream.UserRequest{
{
ID: "userid",
Role: getstream.PtrTo("user"),
Custom: map[string]interface{}{
"color": "blue",
},
Name: getstream.PtrTo("This is a test user"),
Image: getstream.PtrTo("link/to/profile/image"),
},
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("User updated successfully: %+v", response.Data.Users)
// Partial update: choose which fields to change
partialResponse, err := client.UpdateUsersPartial(ctx, &getstream.UpdateUsersPartialRequest{
Users: []getstream.UpdateUserPartialRequest{
{
ID: "userid",
Set: map[string]interface{}{
"new-field": "value",
},
Unset: []string{"name"},
},
},
})
if err != nil {
log.Fatal(err)
}
log.Printf("User partially updated: %+v", partialResponse.Data.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>'...],
});
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Deactivate a single user
deactivateResponse, err := client.DeactivateUser(ctx, &getstream.DeactivateUserRequest{
UserID: "<id>",
})
if err != nil {
log.Fatal(err)
}
log.Printf("User deactivated: %+v", deactivateResponse)
// Reactivate users
reactivateResponse, err := client.ReactivateUsers(ctx, &getstream.ReactivateUsersRequest{
UserIds: []string{"<id>"},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Users reactivated: %+v", reactivateResponse)
// Deactivating users in bulk (asynchronous)
bulkDeactivateResponse, err := client.DeactivateUsers(ctx, &getstream.DeactivateUsersRequest{
UserIds: []string{"<id1>", "<id2>"},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Bulk deactivation task ID: %s", bulkDeactivateResponse.Data.TaskID)
}
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");
package main
import (
"context"
"log"
"time"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Example of monitoring the status of an async task
// The logic is same for all async tasks
response, err := client.ExportUsers(ctx, &getstream.ExportUsersRequest{
UserIds: []string{"<user id1>", "<user id2>"},
})
if err != nil {
log.Fatal(err)
}
// Poll the task status
for {
taskResponse, err := client.GetTask(ctx, &getstream.GetTaskRequest{
ID: response.Data.TaskID,
})
if err != nil {
log.Fatal(err)
}
log.Printf("Task status: %s", taskResponse.Data.Status)
if taskResponse.Data.Status == "completed" {
log.Println("Task completed successfully!")
break
} else if taskResponse.Data.Status == "failed" {
log.Println("Task failed!")
break
}
// Wait before polling again
time.Sleep(2 * time.Second)
}
}
Deleting users
client.deleteUsers({ user_ids: ["<id>"] });
//restore
client.restoreUsers({ user_ids: ["<id>"] });
package main
import (
"context"
"log"
"github.com/GetStream/getstream-go/v3"
)
func main() {
client, err := getstream.NewClient("<your_api_key>", "<your_api_secret>")
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Delete users (soft delete by default)
deleteResponse, err := client.DeleteUsers(ctx, &getstream.DeleteUsersRequest{
UserIds: []string{"<id>"},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Users deleted: %+v", deleteResponse)
// Delete users with specific options
deleteWithOptionsResponse, err := client.DeleteUsers(ctx, &getstream.DeleteUsersRequest{
UserIds: []string{"<id>"},
User: getstream.PtrTo("hard"), // soft, pruning, or hard
Messages: getstream.PtrTo("pruning"), // soft, pruning, or hard
Conversations: getstream.PtrTo("soft"), // soft or hard
NewChannelOwnerID: getstream.PtrTo("new-owner-id"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Users deleted with options: %+v", deleteWithOptionsResponse)
// Restore users
restoreResponse, err := client.RestoreUsers(ctx, &getstream.RestoreUsersRequest{
UserIds: []string{"<id>"},
})
if err != nil {
log.Fatal(err)
}
log.Printf("Users restored: %+v", restoreResponse)
}
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");
- I'm working with the Stream Feeds React Native SDK and would like to ask questions about this documentation page: https://getstream.io/activity-feeds/docs/react-native/user-management.md
- View as markdown
- Open in ChatGPT
- Open in Claude