At my company we are starting to amke use of Assistants API and it looks good, but we are worried about data retention by OpenAI.
We understand that storing threads for some time is required, but wem dont want them to be stored forever.
When are threads auto deleted(if that even happens)?
Is there any way to list the threads by API to delete them?
As for the auto deletion, I read here at the forum that it is supposed to be automatically deleted after 60 days, but the documentation says:
Objects related to the Assistants API are deleted from our servers 30 days after you delete them via the API or the dashboard. Objects that are not deleted via the API or dashboard are retained indefinitely.
so I don’t know if that changed or the documentation is not accurate.
Threads are a particular entity that have a expiration assigned to them after inactivity, just so there is no expectation that OpenAI will let you rejoin a chat maintained server-side a year later. This also means you don’t have to manually manage expiration yourself or some limited storage capacity assigned to them.
“Objects” refers to things like assistants definitions or document vector stores, that you wouldn’t want expiring as a developer of the API platform. They go away when you delete them, retained just for some period of safety auditing observation by OpenAI. (you can assign an inactivity expiration to a vector store yourself, though, as they cost you money to maintain).
Your original citation is correct: if unused, threads will be deleted after 60 days of inactivity. If your account was unused for 61 days, you would have 0 threads.
You can (and in most applications like matching chat to customer, must) also maintain your chat in your application database, and delete the thread ID when the user wants to delete a chat session, or reduce the time before you do your own cleanup. You’d also want to anticipate this auto-deletion so you don’t attempt to present a list of chats that cannot be continued on.
And this is how I delete either the threds immidiatly after I am done using them or IF I see in my OpenAI Account under Dashboad>Threads that there are old threds left.
private static async Task DeleteThread(string openAIAccessToken, string threadId)
{
using (var httpClient = new HttpClient())
{
//httpClient.Timeout = TimeSpan.FromMinutes(5); // Increase timeout
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", openAIAccessToken);
httpClient.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2");
var response = await httpClient.DeleteAsync($"https://api.openai.com/v1/threads/{threadId}");
var content = await response.Content.ReadAsStringAsync();
// Print the response content
Log($"Delete Thread Response: {content}");
response.EnsureSuccessStatusCode();
}
}
Getting all still existing Threds:
private static async Task<List<string>> ListAllThreads(string sessionKey)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", sessionKey);
List<string> threadIds = new List<string>();
string lastThreadId = null;
bool hasMore = true;
while (hasMore)
{
var url = "https://api.openai.com/v1/threads?limit=100";
if (lastThreadId != null)
{
url += $"&after={lastThreadId}";
}
var response = await httpClient.GetAsync(url);
var responseContent = await response.Content.ReadAsStringAsync();
// Introduce a delay to avoid hitting rate limits
await Task.Delay(500); // 500 ms delay between requests
if (response.IsSuccessStatusCode)
{
dynamic jsonResponse = JObject.Parse(responseContent);
foreach (var thread in jsonResponse.data)
{
threadIds.Add((string)thread.id);
Log($"Retrieved thread ID: {(string)thread.id}");
}
// Check if there are more items to fetch
hasMore = jsonResponse.data.Count > 0;
if (hasMore)
{
// Update the lastThreadId for the next request
lastThreadId = (string)jsonResponse.data.Last.id;
}
Log("Fetched a batch of threads.");
}
else
{
Log($"Failed to retrieve threads: {response.StatusCode} - {responseContent}");
hasMore = false; // Exit loop on error
}
}
Log($"Total threads retrieved: {threadIds.Count}");
return threadIds;
}
}
Deleting all existing Threads:
List<string> thredIds = await ListAllThreads(openAIAccessToken);
//EXECUTE WHEN YOU WANT TO DELETE ALL EXISTING THREADS
// YOU HAVE TO LOGIN IN THE BROWSER AND FIND© THE SESSION ID FROM THE NETWORK INSPECT, COPY AS NODE.JS FETCH; THE SESSION ID
string sessionKey = "sess-CNjy8xgfbTvedDB6i4yzsYmOHBZZwXp6hkmk4lJL"; // Replace this with your actual current session key
var threads = await ListAllThreads(sessionKey);
int maxParallelism = 5; // Limit the number of concurrent tasks
var tasks = new List<Task>();
foreach (var threadId in threads)
{
tasks.Add(DeleteThread(openAIAccessToken, threadId));
if (tasks.Count >= maxParallelism)
{
await Task.WhenAny(tasks); // Wait for any task to complete
tasks.RemoveAll(t => t.IsCompleted); // Remove completed tasks
}
}
// Wait for all remaining tasks to complete
await Task.WhenAll(tasks);
Log("All threads processed.");