// request data export for multiple users at once
await client.exportUsers({ user_ids: ["<user id1>", "<user id2>"] });
GDPR
Companies conducting business within the European Union are legally required to comply with the General Data Protection Regulation (GDPR).
While many aspects of this regulation may not significantly affect your integration with Stream, the GDPR provisions regarding the right to data access and the right to erasure are directly pertinent.
These provisions relate to data that is stored and managed on Stream’s servers.
The Right to Access Data
GDPR gives EU citizens the right to request access to their information and the right to have access to this information in a portable format. Stream covers this requirement with the user export method.
This method can only be used with server-side authentication:
import (
"context"
"github.com/GetStream/getstream-go/v3"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
// request data export for multiple users at once
request := &getstream.ExportUsersRequest{
UserIds: []string{"<user id1>", "<user id2>"},
}
_, err = client.ExportUsers(context.Background(), request)
import io.getstream.services.framework.StreamSDKClient;
import io.getstream.services.CommonImpl;
import io.getstream.models.ExportUsersRequest;
import java.util.Arrays;
StreamSDKClient client = new StreamSDKClient("api_key", "api_secret");
CommonImpl common = new CommonImpl(client.getHttpClient());
// request data export for multiple users at once
ExportUsersRequest request = ExportUsersRequest.builder()
.userIds(Arrays.asList("<user id1>", "<user id2>"))
.build();
common.exportUsers(request).execute();
use GetStream\Client;
use GetStream\GeneratedModels\ExportUsersRequest;
$client = new Client('api_key', 'api_secret');
// request data export for multiple users at once
$request = new ExportUsersRequest([
'user_ids' => ['<user id1>', '<user id2>']
]);
$response = $client->exportUsers($request);
using GetStream;
using GetStream.Models;
var client = new StreamClient("api_key", "api_secret");
// request data export for multiple users at once
var request = new ExportUsersRequest
{
UserIds = new[] { "<user id1>", "<user id2>" }
};
var response = await client.ExportUsersAsync(request);
from getstream import Stream
client = Stream('api_key', 'api_secret')
# request data export for multiple users at once
response = client.export_users(['<user id1>', '<user id2>'])
Exporting users 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)
}
// request data export for multiple users at once
request := &getstream.ExportUsersRequest{
UserIds: []string{"<user id1>", "<user id2>"},
}
_, err = client.ExportUsers(context.Background(), request)
import io.getstream.services.framework.StreamSDKClient;
import io.getstream.services.CommonImpl;
import io.getstream.models.ExportUsersRequest;
import java.util.Arrays;
StreamSDKClient client = new StreamSDKClient("api_key", "api_secret");
CommonImpl common = new CommonImpl(client.getHttpClient());
// Example of monitoring the status of an async task
// The logic is same for all async tasks
var response = common.exportUsers(ExportUsersRequest.builder()
.userIds(Arrays.asList("<user id1>", "<user id2>"))
.build()).execute();
// you need to poll this endpoint
var taskResponse = common.getTask(response.getData().getTaskId()).execute();
System.out.println(taskResponse.getData().getStatus().equals("completed"));
use GetStream\Client;
use GetStream\GeneratedModels\ExportUsersRequest;
$client = new Client('api_key', 'api_secret');
// Example of monitoring the status of an async task
// The logic is same for all async tasks
$response = $client->exportUsers(new ExportUsersRequest([
'user_ids' => ['<user id1>', '<user id2>']
]));
// you need to poll this endpoint
$taskResponse = $client->getTask($response->getData()->getTaskId());
echo $taskResponse->getData()->getStatus() === 'completed';
using GetStream;
var client = new StreamClient("api_key", "api_secret");
// Example of monitoring the status of an async task
// The logic is same for all async tasks
var request = new ExportUsersRequest
{
UserIds = new[] { "<user id1>", "<user id2>" }
};
var response = await client.ExportUsersAsync(request);
// you need to poll this endpoint
var taskResponse = await client.GetTaskAsync(response.Data.TaskId);
Console.WriteLine(taskResponse.Data.Status == "completed");
from getstream import Stream
client = Stream('api_key', 'api_secret')
# Example of monitoring the status of an async task
# The logic is same for all async tasks
response = client.export_users(['<user id1>', '<user id2>'])
# you need to poll this endpoint
task_response = client.get_task(response.data.task_id)
print(task_response.data.status == "completed")
The Right to Erasure
The GDPR also grants EU citizens the right to request the deletion of their personal information.
Stream offers mechanisms to delete users and feeds in accordance with various use cases, ensuring compliance with these regulations.
The operations performed on users, such as updating and deleting, have an effect on all products (chat, feeds and video).
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)
import io.getstream.services.framework.StreamSDKClient;
import io.getstream.services.CommonImpl;
import io.getstream.models.DeleteUsersRequest;
import io.getstream.models.RestoreUsersRequest;
import java.util.Arrays;
StreamSDKClient client = new StreamSDKClient("api_key", "api_secret");
CommonImpl common = new CommonImpl(client.getHttpClient());
// Delete users
DeleteUsersRequest deleteRequest = DeleteUsersRequest.builder()
.userIds(Arrays.asList("<id>"))
.build();
common.deleteUsers(deleteRequest).execute();
// Restore users
RestoreUsersRequest restoreRequest = RestoreUsersRequest.builder()
.userIds(Arrays.asList("<id>"))
.build();
common.restoreUsers(restoreRequest).execute();
use GetStream\Client;
use GetStream\GeneratedModels\DeleteUsersRequest;
use GetStream\GeneratedModels\RestoreUsersRequest;
$client = new Client('api_key', 'api_secret');
// Delete users
$deleteRequest = new DeleteUsersRequest([
'user_ids' => ['<id>']
]);
$client->deleteUsers($deleteRequest);
// Restore users
$restoreRequest = new RestoreUsersRequest([
'user_ids' => ['<id>']
]);
$client->restoreUsers($restoreRequest);
using GetStream;
var client = new StreamClient("api_key", "api_secret");
// Delete users
var deleteRequest = new DeleteUsersRequest
{
UserIds = new[] { "<id>" }
};
await client.DeleteUsersAsync(deleteRequest);
// Restore users
var restoreRequest = new RestoreUsersRequest
{
UserIds = new[] { "<id>" }
};
await client.RestoreUsersAsync(restoreRequest);
from getstream import Stream
client = Stream("api_key", "api_secret")
# Delete users
client.delete_users(["<id>"])
# Restore users
client.restore_users(["<id>"])
# Please refer to the Node.js examples above for the API structure
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")
import io.getstream.services.framework.StreamSDKClient;
import io.getstream.services.CommonImpl;
import io.getstream.models.ExportUsersRequest;
import java.util.Arrays;
StreamSDKClient client = new StreamSDKClient("api_key", "api_secret");
CommonImpl common = new CommonImpl(client.getHttpClient());
// Example of monitoring the status of an async task
// The logic is same for all async tasks
var response = common.exportUsers(ExportUsersRequest.builder()
.userIds(Arrays.asList("<user id1>", "<user id2>"))
.build()).execute();
// you need to poll this endpoint
var taskResponse = common.getTask(response.getData().getTaskId()).execute();
System.out.println(taskResponse.getData().getStatus().equals("completed"));
use GetStream\Client;
use GetStream\GeneratedModels\ExportUsersRequest;
$client = new Client("api_key", "api_secret");
// Example of monitoring the status of an async task
// The logic is same for all async tasks
$response = $client->exportUsers(new ExportUsersRequest([
"user_ids" => ["<user id1>", "<user id2>"]
]));
// you need to poll this endpoint
$taskResponse = $client->getTask($response->getData()->getTaskId());
echo $taskResponse->getData()->getStatus() === "completed";
using GetStream;
var client = new StreamClient("api_key", "api_secret");
// Delete users
var deleteRequest = new DeleteUsersRequest
{
UserIds = new[] { "<id>" }
};
await client.DeleteUsersAsync(deleteRequest);
// Restore users
var restoreRequest = new RestoreUsersRequest
{
UserIds = new[] { "<id>" }
};
await client.RestoreUsersAsync(restoreRequest);
from getstream import Stream
client = Stream("api_key", "api_secret")
# Delete users
client.delete_users(["<id>"])
# Restore users
client.restore_users(["<id>"])
# Please refer to the Node.js examples above for the API structure