Migrate OpenAI Assistants threads, runs and file search to the Responses API
Map Assistants threads, runs and file search to Responses after the shutdown. Recover saved history and decide which state your application should own.
To migrate from OpenAI Assistants to Responses, rebuild conversation state from messages your application saved, replace Runs with Responses, and configure file_search with explicit vector store IDs. OpenAI shut down the Assistants API on August 26, 2026; its Thread-message retrieval calls no longer work. Conversations can own the new history, or your application can retain it and send the required context on each request.
That distinction matters because an Assistants integration bundled configuration, server-side history and execution into a small set of persistent objects. A hurried migration can reproduce the same coupling under new names without deciding who should own state, tools, retries, retention and observability.
Treat this as an architecture migration. Inventory each responsibility first, choose where it should live, then move traffic. The goal is not only to restore a working request. It is to make the next provider, model or API transition smaller than this one.
What replaces Assistants, Threads, Runs and Run steps?
The official mapping is a useful starting point:
- Assistant → Prompt or request configuration: model, instructions, tools and defaults.
- Thread → Conversation: durable interaction state.
- Run → Response: one execution against current input and state.
- Run step → Item: a message, tool call, tool output or other event.
This mapping is not a complete migration plan. It says what OpenAI objects replace the old objects, but it does not decide which parts your application should continue to delegate to a provider.
Separate the workload into five concerns:
- Configuration: model selection, instructions, tool definitions, schemas and generation controls.
- State: messages, tool calls, tool results, files, metadata and retention.
- Execution: streaming, background work, cancellation, retries and tool loops.
- Capabilities: file search, code execution, functions, MCP and other provider tools.
- Operations: usage, traces, errors, evaluation, authorization and rollback.
For each concern, record the current Assistants behavior, the target owner and the evidence that proves parity. This prevents a successful text response from hiding a broken tool loop or missing conversation history.
Choose a target state model deliberately
Responses supports more than one way to continue an interaction. The choice affects retention, portability and how much state your application owns.
Provider-managed Conversations
A Conversation stores a durable stream of Items. Unlike a Thread, it can contain messages, tool calls, tool outputs and other typed data rather than only messages. A Response can attach new input and output Items to that Conversation.
This is the closest conceptual replacement for Threads. It fits when you want OpenAI to persist the interaction and when provider-native tools and item semantics are central to the product.
The trade-off is deliberate provider coupling. Your application stores a Conversation identifier and depends on OpenAI's item model, retention behavior and migration surface.
Chained Responses
A request can use previous_response_id to continue from an earlier Response without creating a Conversation object. This is useful for short-lived chains or workflows that do not need a separately managed durable conversation.
It is not free context. OpenAI's conversation-state guide says previous input tokens in the chain are still billed as input tokens. Its data-controls reference documents at least 30 days of Responses application-state retention by default or with store: true, with exceptions for particular modes and data controls. Conversations and their Items persist until deleted. Choose the storage policy explicitly; a response chain is not your application archive.
Application-managed history
Your application can store the canonical interaction and send the required input on each request. This gives you direct control over retention, redaction, model switching and provider portability.
It also makes you responsible for context assembly, truncation, compaction, replaying tool state and avoiding duplicate execution. Reasoning-capable and tool-using models may return opaque or signed state that must survive the next turn, so “store the text messages” is no longer a sufficient design.
Do not choose among these models based only on which requires the fewest code changes. Choose based on data ownership, provider portability, tool semantics and operational capability.
Do not blindly migrate Assistants into another temporary object
The official guide still describes creating reusable Prompt objects from Assistants in the dashboard. It also warns that those Prompt objects are deprecated. OpenAI's deprecation schedule lists November 30, 2026 as the shutdown date for v1/prompts. Treat the conversion instructions as a transition path, not a durable configuration design.
That warning changes the migration decision.
If your workload needs provider-managed prompt versioning during a short transition, the conversion path can still be useful. If you are designing the durable target, first ask whether configuration should live in:
- version-controlled application configuration;
- request-level
instructions, model and tool declarations; - a provider-independent AI gateway;
- or a provider Prompt object whose lifecycle you accept explicitly.
Do not introduce a second migration merely because the dashboard offers an automatic conversion. The durable abstraction is the configuration contract — instructions, tools, model policy and schema — not the identifier of the object that stores it today.
How do you migrate Threads after the Assistants shutdown?
Start new chats on the replacement path, then backfill active history from your own saved messages or pre-shutdown exports. The official migration guide explicitly labels its Thread-reading example as a pre-sunset workflow: openai.beta.threads.messages.list no longer works.
Do not build a recovery job around that removed call. If you have only Thread IDs, the documented migration path cannot reconstruct their messages. Record the gap and provide a controlled restart experience instead of inventing conversation history.
A Thread backfill must transform content. Threads stored messages; Conversations store typed Items. User text becomes input text, assistant text becomes output text, and image or file content must be converted to the target item shape. Tool calls and results need their identifiers and ordering preserved where they are part of the history you intend to continue.
Before writing a backfill job, classify the Thread history you retained:
- Active: recent conversations that users are likely to resume.
- Record only: history that must remain readable but does not need model continuation.
- Expired: data eligible for deletion under the product retention policy.
- Exceptional: conversations containing unsupported content, incomplete Runs or tool state that requires manual handling.
Migrate active conversations first. Keep an immutable mapping from the old Thread ID to the new Conversation ID, plus migration status, item counts and a content hash or other reconciliation evidence. Preserve your saved source records during reconciliation, subject to your retention policy.
Replace Run polling and tool handoffs explicitly
A Run looked like one server-managed process attached to a Thread. A Response is simpler at the top level — input Items go in and output Items come back — but the application must still account for the execution lifecycle.
Inventory every Run behavior your product relies on:
- queued and in-progress status polling;
- streaming events;
- cancellation;
- expiration and timeout behavior;
requires_actiontool handoffs;- parallel tool calls;
- incomplete or failed terminal states;
- usage recorded at completion;
- background execution and webhook delivery.
Then map each behavior to Responses, background mode, streaming or application logic. A synchronous test that returns final text does not prove parity with an asynchronous Run workflow.
OpenAI's function-calling flow returns function_call Items; your code executes the function and supplies function_call_output with the matching call_id. Do not replace requires_action polling with a request that ignores these output Items.
Tool loops deserve their own state machine. Persist the Response or Item identifier, tool-call identifier, validated arguments, execution result and retry status before sending tool output back to the model. Use application-level idempotency for tools with side effects. A retried model request must not send the same email, charge the same order or modify the same record twice. The tool-call idempotency guide explains how to distinguish a retried business operation from a genuinely new one.
Where do file search, vector stores and other tools go?
For OpenAI Responses, configure the hosted file_search tool in tools with vector_store_ids. Creating a Conversation does not select a knowledge base. Resolve the authorized stores for the current user or tenant in your application; do not assume an old Thread's tool_resources carries over.
Verify that each required store and file still exists, is accessible and has finished indexing. Keep original documents for anything that must be re-ingested. Check answer citations and request include: ["file_search_call.results"] when you need the retrieved evidence for comparison. Moving retrieval to external RAG requires its own ingestion and relevance validation, not a rename of OpenAI vector store IDs.
“Supports tools” is too broad to be an acceptance criterion.
Function calling requires schemas, argument validation, authorization, idempotency and result replay. File search requires a plan for files, vector stores, indexing state, citations and deletion. Code execution requires sandbox, file and timeout behavior. MCP introduces server authentication, tool discovery and a separate trust boundary. Computer use adds action authorization and a visual execution loop.
Build a capability matrix for every Assistant. At minimum, record these transitions and their parity evidence:
- Instructions: from Assistant configuration to a Prompt, request or gateway; validate with golden behavior tests.
- Functions: from Assistant tools to Responses functions or gateway tools; validate tool selection and side effects.
- Retrieval: from file search and vector stores to Responses file search or external RAG; measure retrieval quality and verify citations.
- Code execution: from Code Interpreter to a Responses tool or owned sandbox; test files, timeouts and failures.
- Conversation state: from a Thread to a Conversation or application store; test resume behavior and ordering.
- Run lifecycle: from Runs and Run steps to Responses, Items and explicit orchestration; test streams, retries and terminal states.
Do not mark a capability complete because the target has a feature with a similar name. Test the behavior your product actually depends on.
When should you use an AIVAX gateway instead of provider-owned state?
AIVAX AI Gateways centralize model selection, provider connection, instructions, RAG collections, skills, tools, MCP sources, moderation, workers and generation controls. Applications call a gateway through the OpenAI-compatible /v1/chat/completions endpoint, setting model to its full ID or, with a private API key, its slug. Public keys require the full gateway ID.
This makes a gateway a useful target for the configuration and capability responsibilities that previously lived in an Assistant. It can reduce provider-specific model routing and keep instructions, retrieval, tools and safety controls out of each application request.
It is not a drop-in implementation of the OpenAI Responses or Conversations APIs. AIVAX does not expose a public /v1/responses endpoint. On chat completions, its conversation token identifies a logging record; it does not replace the message history the application sends. Updating that record replaces its stored messages with the current call's resulting transcript, rather than reconstructing omitted turns.
If you choose the AIVAX route, use an application-owned state model:
- Store the canonical conversation and tool state in your application.
- Send the relevant OpenAI-compatible message history to the gateway.
- When conversation logging is enabled, use a stable
idempotency_keyper conversation to update the same AIVAX conversation record. It neither restores previous messages nor prevents repeated inference or tool side effects; see the request-correlation contract. - Configure model policy, instructions, RAG and tools in the gateway.
- Keep side-effect authorization and idempotency in application code.
- Validate the gateway with the same task and tool-loop tests used for the old Assistant.
This route trades provider-managed conversation state for a more portable application contract. It is appropriate when portability and centralized AI operations matter more than direct access to Responses-native state and tools.
If your product depends heavily on OpenAI Conversations, hosted file search, background Responses or provider-specific Items, migrate to Responses first. A gateway should not be inserted where it would hide required semantics.
Cut over new traffic before backfilling history
A safe migration separates forward traffic from historical data.
Phase 1: recover the inventory
Recover Assistant configuration, Thread mappings, tool schemas and Run behavior from source control, saved records and pre-shutdown exports. Check vector stores and file dependencies through the supported APIs. Mark missing records explicitly; do not assume a fresh Assistants export is available. Establish task-level regression cases from real, sanitized workloads.
Phase 2: build the target path
Implement the selected state model and one complete execution path, including tools and failures. Add correlation IDs that connect application requests, model calls, tool executions and final outcomes.
Phase 3: replay and compare
Use captured baselines and deterministic fixtures rather than attempting live Assistants calls. Compare task outcome, tool choice, retrieval evidence, latency, usage and error behavior where your saved records support that comparison. Do not compare text equality; model outputs are non-deterministic.
Phase 4: route new conversations
Send newly created chats to the target. For existing sessions, restore verified history or return a controlled migration or restart experience. Do not route users back to removed Assistants endpoints as a rollback strategy.
Phase 5: migrate active history
Backfill only conversations that need continuity. Reconcile item counts and supported content, record exceptions, and preserve the old-to-new identifier mapping.
Phase 6: remove legacy dependencies
Delete Assistants client calls, polling jobs, webhook handlers and feature flags only after traffic, logs and dependency scans show no remaining use. Retain migration evidence according to your audit and data-retention requirements.
Validate outcomes, not object creation
A migration test suite should exercise complete user goals. At minimum, cover:
- a single-turn answer;
- a multi-turn conversation resumed after process restart;
- one read-only tool call;
- one side-effecting tool call with a forced retry;
- parallel or sequential tool calls if supported;
- file input and retrieval with source verification;
- streaming interruption and recovery;
- cancellation or timeout;
- context growth near the model limit;
- malformed tool arguments;
- provider 429 and transient 5xx responses;
- an old conversation with unsupported content;
- usage and cost attribution;
- deletion and retention behavior.
Grade the final task outcome, the evidence used and the safety of the execution path. Endpoint status and object IDs are implementation checks, not proof that the assistant still works.
AIVAX Agentic Tests can evaluate bounded, multi-turn goals through an AI Gateway with a simulated user and a separate LLM judge. The multi-turn testing walkthrough shows how to define a goal and inspect the conversation evidence. They are useful for the gateway route because the evaluation follows the conversation outcome across turns rather than scoring one response in isolation. They do not replace deterministic tool authorization, migration reconciliation or provider contract tests.
Use this migration to reduce the next one
The Assistants shutdown exposes a common architecture problem: product behavior was attached to a provider's storage and execution objects rather than expressed as explicit application contracts.
Before cutover, record who owns configuration, conversation state, tool execution and retention.
Responses and Conversations are the closest OpenAI migration path. An application-owned history plus an AI Gateway is a portability-oriented alternative. Document any Responses-native behavior the gateway route cannot preserve.
Frequently asked questions
Can I recover old Threads after the Assistants API shutdown?
Use messages your application saved or exported before shutdown. OpenAI's migration guide says the old Thread-message retrieval call no longer works. A Thread ID alone is not enough for the documented backfill. Convert retained content into Conversation Items, reconcile it, and disclose any missing history to the user.
Does an AIVAX conversation token replace an OpenAI Thread?
No. On AIVAX chat completions, idempotency_key supplies a conversation token for logging when conversation logging is enabled. It does not fetch earlier turns into the next request or prevent a repeated tool side effect. Your application must send the relevant message history and enforce operation-level idempotency.