List and delete all threads

The assistants API allow you to create, retrieve, modify, and delete threads. But there seems to be no way to list or delete all threads.

This means that if I programmatically create a bunch of threads (whether or not I add messages to them), those threads will presumably be idle somewhere attached to the assistant.

It would be nice to have an way to list and/or delete all threads for the sake of housekeeping. Or does this not matter?

9 Likes

Yeah. It actually freaked me out when I first tested it a couple of times. I was not able to delete a couple of threads. I was afraid it will go on and on and accumulate charges. lol

3 Likes
3 Likes

Using the python requests library and the session token from above, this looks like…

import requests as req

url = "https://api.openai.com/v1/threads"
headers = {
    "Authorization": f"Bearer {token}", 
    "Openai-Organization": f"{org}", 
    "OpenAI-Beta": "assistants=v1"
}

resp = req.get(url, headers=headers)

A full script to delete all threads:

import requests as req
from alive_progress import alive_it

token = "the_token"
org = "myorg"
url = "https://api.openai.com/v1/threads"

headers = {
    "Authorization": f"Bearer {token}", 
    "Openai-Organization": f"{org}", 
    "OpenAI-Beta": "assistants=v1"
}
params = {"limit": 10}
resp = req.get(url, headers=headers, params=params)
ids = [t['id'] for t in resp.json()['data']]

while len(ids) > 0:
    for tid in alive_it(ids, force_tty=True):
        client.beta.threads.delete(tid)
        time.sleep(1)
    resp = req.get(url, headers=headers, params=params)
    ids = [t['id'] for t in resp.json()['data']]

6 Likes

This still works however I found that I had to add my project key as well. You can find it in your profile settings and in the inspector.

I expanded on this and posted python code a while back, giving an “organization explorer”, using web’s oauth mechanism instead to get account information and session key, then letting you list all organizations and projects within them, then a demo of listing that project’s threads (or the playground’s threads) where you could then continue writing the actual deleting.

omg, how there is possible no list api??! :frowning:

Version for node, if anybody runs into this

import OpenAI from "openai"

const openai = new OpenAI()
type Thread = {
  id: string
  object: string
  created_at: number
  metadata: Record<string, any>
  tool_resources: {
    code_interpreter: {
      file_ids: string[]
    }
  }
}

type ThreadListResponse = {
  object: string
  data: Thread[]
  first_id: string
  last_id: string
  has_more: boolean
}
async function main() {
  const response = await fetch("https://api.openai.com/v1/threads?limit=30", {
    credentials: "include",
    headers: {
      Accept: "*/*",
      "Accept-Language": "en-US,en;q=0.9",
      Authorization: "Bearer sess-xxx", // update it 
      "OpenAI-Beta": "assistants=v2",
      "OpenAI-Organization": "org-xxx",  // update it 
      "OpenAI-Project": "proj_xxx",  // update it 
      "User-Agent":
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10)"
    },
    method: "GET",
    mode: "cors",
    redirect: "follow",
    referrer: "https://platform.openai.com/",
    referrerPolicy: "strict-origin-when-cross-origin"
  })

  if (!response.ok) {
    console.error("Failed to fetch thread list:", response.statusText)
  }

  const threadList = (await response.json()) as ThreadListResponse

  console.log("Threads:", threadList)

  const threadIds = threadList.data.map((thread) => thread.id)
  for (const threadId of threadIds) {
    try {
      const response = await openai.beta.threads.del(threadId)
      console.log(`Deleted thread with ID: ${threadId}`, response)
    } catch (error) {
      console.error(`Failed to delete thread with ID: ${threadId}`, error)
    }
  }
}

main()

OPENAI_API_KEY=sk-xxx-xxx ts-node deleteThreads.ts

There is probably bit more work needed to handle pagination.

I used “metadata” field available in the Assistant structure to store the association between assistant and thread so that I don’t need a complete list of all threads.