AIARTICLE

OpenAI shuts down the Assistants API: the migration guide for anyone with agents in production

Since August 26, 2026, the Assistants API no longer responds. Anyone who still had Threads, Runs, or Assistants in production needs to migrate to the Responses API, and OpenAI's official documentation shows where the contract really changes.

An ending that has already happened

OpenAI's Assistants API is no longer a deprecated option, it's an API that has stopped responding. According to the official migration guide published in OpenAI's documentation, the shutdown happened on August 26, 2026: any call to openai.beta.threads or openai.beta.threads.runs from that date on simply no longer works. This changes the tone of the article: it's not a warning that 'it's going to end', it's a call to anyone still stuck with broken production, a month after the deadline, trying to figure out what to do with Threads, Runs, File Search, and Code Interpreter that depended on that API.

The recommended replacement is the Responses API, already used by a good share of those who built more recent agents. OpenAI summarizes the change in a table of equivalences that's worth understanding item by item, because no piece migrates 1 to 1.

| Before (Assistants API) | Now (Responses API) | Why | |---|---|---| | Assistants | Prompts | Configuration becomes versioned, outside the code | | Threads | Conversations | Store items, not just messages | | Runs | Responses | The tool loop becomes explicit | | Run steps | Items | Generic object: message, tool call, or output |

From threads to conversations: messages stop being the unit

In the Assistants API, a thread was a collection of messages stored on OpenAI's server. That's it: text input and output, associated with a thread_id. In the Responses API this container is now called a conversation, and the difference isn't just in the name: a conversation stores items, a broader category that includes messages, tool calls, and the outputs of those tools within the same history.

In practice, this means that code that just stacked role and content to reconstruct context now needs to handle a heterogeneous history. The documentation's own example shows the change:

python
# Before
thread = openai.beta.threads.create(
 messages=[{"role": "user", "content": "question"}],
 metadata={"user_id": "peter"},
)

# Now
conversation = openai.conversations.create(
 items=[{"role": "user", "content": "question"}],
)

Anyone who had audit or conversation-replay logic built around thread.messages.list() will need to rewrite it to iterate over items, and handle each type (message, tool call, tool output) distinctly instead of assuming everything is text.

From runs to responses: the tool loop is now yours

This is, in this guide's reading, the most painful contract change for anyone with agents using Code Interpreter or custom functions. A run in the Assistants API was an asynchronous process: the client created the run, entered a polling loop checking run.status until it turned completed, and the SDK handled, behind the scenes, much of the required_action orchestration whenever there was a pending tool call.

In the Responses API, that asynchronous status no longer exists by default. openai.responses.create() takes the input items and returns the output items in a single call, optionally associated with a conversation_id to keep the history (replacing the old habit of manually passing along previous_response_id). OpenAI's text is direct about this: responses are designed to be used in isolation, but they also accept prompt and conversation to store configuration and context.

The point the guide makes explicit, and that changes the design of any agent with tools, is that "tool call loops are explicitly managed": there is no longer a run's required_action taking care of pausing and resuming execution when a function needs to be called. Anyone who had a Code Interpreter or function-calling agent that depended on that automatic run cycle needs to rewrite that loop in their own orchestration code, explicitly deciding when to resend a tool's output as new input.

Assistants disappear, prompts step in (dashboard only)

The second contract change is organizational, not just technical. An Assistant was an API object: created, updated, and deleted through POST/PATCH/DELETE calls, with model, instructions, and tools embedded in it. Its replacement, the prompt, can only be created through OpenAI's dashboard, not through the API. This is a deliberate choice, according to the documentation: prompts are meant to be versioned, reviewed, and compared as a product artifact, not generated programmatically on every deploy.

The practical consequence is that teams that automated assistant creation via CI/CD, for example creating one assistant per tenant or per experiment, lose that path. The guide suggests storing the prompt's ID (or the exported spec) in version control, and switching prompts by ID to run A/B tests, instead of creating and deleting assistant objects at runtime. It's a loss of programmatic flexibility in exchange for traceability: you can audit exactly which prompt version produced which response, something the Assistants API didn't offer natively.

File Search and Code Interpreter: the gap the guide doesn't close

Here's the point that matters most to anyone who actually had RAG in production with File Search, or code execution with Code Interpreter, and not just a simple chatbot. OpenAI's migration guide documents the swap of threads, runs, and assistants in detail, with side-by-side code examples in Python and Go. But, in the version of the documentation consulted, there isn't the same step-by-step treatment for migrating the File Search and Code Interpreter configurations that existed inside an Assistant.

Both tools continue to exist as platform capabilities, listed separately in the documentation structure under "Search and retrieval" and "Computer and code", which suggests they were reorganized as general-purpose tools, also pluggable into the Responses API, MCP, and the Agents SDK, and no longer tied to the Assistant object. Except that's an inference from the index structure, not an explicit migration instruction for file indexes, vector stores, and code-execution results that used to live inside an assistant's tool_resources. For anyone who had an entire RAG pipeline configured that way, the practical recommendation is to treat this part of the migration as a rebuild, not a field-name swap: it's worth revisiting the vector store configuration and reimplementing it by looking at the specific file search and code interpreter documentation within the Responses API, instead of expecting an automatic mapping.

Migration roadmap for anyone who still hasn't moved

For anyone reaching this point with production still dependent on the discontinued API, a reasonable path, following the logic proposed by the guide itself, is:

  1. Survey each existing Assistant and document its instructions + tools pair before the old dashboard also goes offline.
  2. Recreate that set as a prompt in the current dashboard, storing the ID in version control alongside the application code.
  3. Replace the threads.create + runs.create call with responses.create, passing the conversation_id to keep history between calls.
  4. Rewrite the run.status polling as an explicit tool-call loop, handling each output item (message, function call, result) without assuming the SDK will pause and resume on its own.
  5. Separately audit any File Search or Code Interpreter configuration, treating this part as a reimplementation rather than a find-and-replace of field names.

The gain OpenAI states for anyone completing this migration includes access to features that didn't exist in the Assistants API, such as deep research, MCP, and computer use, plus more direct conversation management in place of manually chaining previous_response_id. For Brazilian teams with agents in production, this means the effort of rewriting the tool loop tends to pay off in new features, but the real cost is concentrated exactly where the official guide is thinnest: in rebuilding the RAG and code execution that used to come ready-made inside the Assistant.

Translated from the Brazilian Portuguese original · Read the original

View profile →