OpenAI Assistants API Is Gone: How to Migrate to Responses API in 2026
OpenAI's Assistants API was officially sunset on August 26, 2026 and is no longer available. If a production application still depends on Assistants, Threads or Runs, this is no longer a future deprecation task: the integration needs to move to the Responses API and, where persistent server-side conversation state is required, the Conversations API.
The migration is not a simple endpoint rename. OpenAI now separates configuration, conversation state and execution differently, and your application takes more explicit responsibility for orchestration. There is another trap as well: OpenAI's migration guide maps Assistants to reusable Prompt objects, but those Prompt objects are themselves scheduled to shut down on November 30, 2026.
The durable migration is therefore:
Assistant configuration
→ application-owned configuration
Threads
→ Conversations or application-owned history
Runs
→ Responses
Run steps
→ Response/Conversation itemsThis guide shows what changed, what can still be migrated after the shutdown, and how to avoid finishing one forced migration only to schedule another.
Is the OpenAI Assistants API still available?
No.
OpenAI's current Assistants migration guide states that the Assistants API was officially sunset on August 26, 2026 and is no longer available.
OpenAI's deprecations page lists the same shutdown date and gives the recommended replacement as:
- Responses API
- Conversations API
This distinction matters because older articles and code examples may still describe the shutdown as an upcoming deadline.
As of August 31, 2026, code built around patterns such as:
openai.beta.assistants
openai.beta.threads
openai.beta.threads.runsshould be treated as legacy migration code, not a supported production architecture.
What replaces Assistants, Threads and Runs?
OpenAI's migration guide publishes this conceptual mapping:
| Assistants API | Current direction | Engineering consequence |
|---|---|---|
| Assistants | Prompts in the migration guide | Configuration is separated from execution |
| Threads | Conversations | Conversation state becomes a stream of items, not only messages |
| Runs | Responses | Model execution moves to Responses |
| Run steps | Items | Messages, tool calls and outputs share a more general item model |
The table is useful, but following it mechanically creates a problem.
Do not automatically migrate Assistants into long-lived Prompt objects
OpenAI's own migration guide warns that reusable Prompt objects are also deprecated.
OpenAI's deprecations page says:
- reusable Prompt deprecation was announced on June 3, 2026
- the __INLINE_CODE_0__ API and reusable Prompt objects are scheduled to shut down on November 30, 2026
- the recommended migration is to move reusable prompt content into application code
So this path has a very short shelf life:
Assistant
→ reusable Prompt
→ migrate again before November 30For a new migration started after the Assistants shutdown, a more durable architecture is usually:
Application repository/config store
├── model policy
├── instructions
├── tool definitions
└── output contract
↓
Responses APIThat is not a workaround. OpenAI's current text-generation documentation explicitly supports passing high-level behaviour through the __INLINE_CODE_0__ parameter, while the Responses API accepts tool definitions directly in the request.
A durable Node.js configuration pattern
Instead of creating one persistent Assistant object per agent, keep the agent contract in application-owned configuration.
For example:
// agents/support-agent.js
export const supportAgent = {
model: 'gpt-5.6',
instructions: `
You are the support assistant for our SaaS.
Answer from approved product knowledge.
Never invent account or billing state.
Use tools when live account data is required.
`,
tools: [
{
type: 'function',
name: 'get_account_status',
description: 'Get the current account status for an authenticated user.',
parameters: {
type: 'object',
properties: {
userId: { type: 'string' }
},
required: ['userId'],
additionalProperties: false
},
strict: true
}
]
}Then pass that contract into Responses:
import OpenAI from 'openai'
import { supportAgent } from './agents/support-agent.js'
const openai = new OpenAI()
export async function createSupportTurn({ conversationId, text }) {
return openai.responses.create({
model: supportAgent.model,
instructions: supportAgent.instructions,
tools: supportAgent.tools,
conversation: conversationId,
input: [
{
role: 'user',
content: text
}
]
})
}The exact model and tools should match your production requirements. The architectural point is that configuration is versioned with the code or configuration system that depends on it.
This gives you normal software controls:
- Git history
- code review
- environment promotion
- automated tests
- rollback
- tenant-specific configuration
- feature flags
It also avoids making November's Prompt-object shutdown your next emergency.
Threads become Conversations, but the state model is broader
An Assistants Thread stored messages.
The current conversation-state documentation says a Conversation is a long-running object with a durable identifier that can be reused across sessions, devices or jobs.
Conversations store items, which can include:
- messages
- tool calls
- tool outputs
- other response data
A basic Node.js flow looks like:
const conversation = await openai.conversations.create()
const response = await openai.responses.create({
model: 'gpt-5.6',
conversation: conversation.id,
instructions: 'Answer questions about the product accurately.',
input: [
{
role: 'user',
content: 'How do I change my subscription?'
}
]
})
console.log(response.output_text)Store the Conversation ID against your own user/session/domain record rather than passing it around anonymously.
For example:
users
id
ai_conversations
id
user_id
provider
provider_conversation_id
created_at
archived_atThat keeps OpenAI's identifier as an integration detail instead of turning it into your application's primary business identity.
Should you use Conversations or __INLINE_CODE_0__?
OpenAI supports two main server-managed continuation patterns with Responses.
Use a Conversation when the dialogue is a durable product object
Choose Conversations when the state should survive across:
- sessions
- devices
- background jobs
- multiple application requests
Examples include:
- customer-support assistants
- long-running onboarding assistants
- persistent research workspaces
- account-bound AI conversations
OpenAI says Conversation objects and their items are not subject to the default 30-day Response-object TTL.
Use __INLINE_CODE_0__ for simpler response chains
OpenAI also supports chaining Responses by passing the prior response ID:
const first = await openai.responses.create({
model: 'gpt-5.6',
input: 'Explain our refund policy.'
})
const second = await openai.responses.create({
model: 'gpt-5.6',
previous_response_id: first.id,
input: 'Summarise that in two bullets.'
})This is useful when you need continuity without creating a separate Conversation object.
However, OpenAI's documentation notes two important details:
- Response objects are stored for 30 days by default, unless storage is disabled or the response is attached to a Conversation.
- Even when using __INLINE_CODE_0__, previous input tokens in the chain are still billed as input tokens.
So choose the state model intentionally rather than using __INLINE_CODE_0__ as a permanent conversation database.
What happened to the Run lifecycle?
Assistants applications often looked like this:
Create message
→ create Run
→ poll Run status
→ requires_action?
→ submit tool outputs
→ continue polling
→ read messagesResponses removes the old Run object.
OpenAI's migration guide says Runs become Responses and that tool-call loops are explicitly managed.
That changes application responsibility.
Your orchestration layer now needs to know how to:
- inspect response items
- identify function calls
- execute approved application functions
- send tool outputs back
- handle retries/timeouts
- enforce limits on tool loops
- record tool failures
For a function tool, the high-level flow becomes:
User input
↓
Responses API
↓
Function call requested?
├─ no → return answer
└─ yes
↓
Validate arguments
↓
Authorise action
↓
Execute application function
↓
Send function-call output
↓
Responses API
↓
Final answer / another permitted tool callThis explicit loop is a feature from an architecture perspective: your application can put authorization, auditing, timeouts and budget controls around tool execution.
It is also code that must be tested. Do not treat it as a one-line endpoint migration.
What happens to old Thread history after the shutdown?
This is now one of the most important migration questions because August 26 has already passed.
OpenAI's current migration guide says to start new chats with Conversations and Responses and to preserve earlier conversation history using messages already stored by your application.
The guide also states that the old Assistants API call for retrieving Thread messages no longer works after sunset.
That means your recovery options depend on what you retained before the shutdown.
If your application already stored message history
You can map that history into a new Conversation or reconstruct the context your product actually needs.
A sensible migration job should preserve:
internal user/conversation ID
old Thread ID for audit/reference
message role
message text/content
message timestamp
new Conversation ID
migration statusDo not make migration depend only on a provider ID.
If your database stored only Thread IDs
Do not write a migration script that assumes it can still call the legacy Thread-message endpoint. OpenAI's current guide explicitly says that retrieval call no longer works.
First inventory what conversation content exists in your own:
- application database
- event logs
- analytics/event pipeline
- support transcripts
- backups
- data exports retained before shutdown
Only migrate data you can actually verify and are permitted to retain.
Do not fabricate missing conversation history or silently pretend a new empty Conversation contains the old context.
Should you migrate every historical conversation?
Usually not.
A forced API migration is a good moment to decide what history still has product value.
Use a retention decision such as:
| Conversation type | Suggested migration decision |
|---|---|
| Active customer conversation | Migrate required context |
| Recently active support thread | Migrate if continuity matters |
| Closed historical thread | Archive in your own system rather than rehydrate automatically |
| Test/development thread | Usually discard |
| Orphaned Thread with no owner | Investigate before migration |
| Data beyond your retention policy | Delete rather than migrate |
Migration should respect your privacy and retention policy, not turn every historical test chat into permanent production state.
File search, vector stores and tools need a separate inventory
Many Assistants integrations were more than conversations.
Before declaring the migration complete, inventory every Assistant resource dependency:
Assistant
├── instructions
├── model selection
├── function tools
├── file search
├── vector stores/files
├── code execution workflows
└── application-side metadataThe Responses API supports built-in tools and function calling, but your application contract has changed.
For each tool, verify:
- the current Responses API schema
- authentication and authorization
- tool-call argument validation
- timeout behaviour
- retry/idempotency behaviour
- audit logging
- error messages returned to the model
- rate and spend limits
Do not port a function definition and assume the surrounding security model migrated with it.
Migration mistake 1: rebuilding on deprecated Prompt objects
The most avoidable mistake in late August 2026 is finishing the Assistants migration by creating a large dependency on reusable Prompt objects.
OpenAI's own migration guide now warns against adopting them for long-lived integrations, and OpenAI's deprecations page schedules them to shut down on November 30, 2026.
For most application-owned agents, prefer:
Versioned instructions in your repository/config service
+
versioned tool schemas
+
Responses API requestIf you have a specific reason to use a short-lived Prompt object during transition, document the November deadline and the second migration explicitly.
Migration mistake 2: treating Conversations as your user database
A Conversation ID is an external provider resource.
It should not replace your own:
- user ID
- account ID
- tenant ID
- case/ticket ID
- authorization model
- retention policy
Your database should decide who is allowed to access a conversation.
OpenAI should receive the conversation reference only after your application has authenticated and authorised the request.
Migration mistake 3: trusting tool calls without authorization
A model requesting a function does not mean the user is authorised to perform it.
Bad pattern:
model calls cancel_subscription
→ backend executes itBetter:
model calls cancel_subscription
→ validate schema
→ authenticate actor
→ check account ownership/role
→ require confirmation if needed
→ execute idempotently
→ audit
→ return tool resultTreat model tool calls as requested actions, not trusted commands.
Migration mistake 4: comparing only text output
A migration can produce plausible answers while still breaking the product.
Test at least:
- conversation continuity
- tool selection
- tool arguments
- permission failures
- file/retrieval behaviour
- structured outputs
- streaming behaviour
- latency
- token usage
- error recovery
- cancellation/timeouts
- duplicate/retry behaviour around external tools
The correct success criterion is not:
"The response looks similar."It is:
"The new workflow preserves the product's required behaviour and controls."A practical post-sunset migration plan
Because the Assistants endpoint is already gone, a team starting now should work in this order.
Step 1: find every legacy dependency
Search the codebase for patterns such as:
beta.assistants
beta.threads
threads.runs
assistant_id
thread_id
run_id
requires_action
submit_tool_outputsAlso search infrastructure, workers, serverless functions and scheduled jobs, not only the main API server.
Step 2: classify each old Assistant
For each Assistant, record:
- business purpose
- model
- instructions
- tools
- file/vector dependencies
- tenants/users depending on it
- whether configuration was dynamic
Then rebuild the configuration in code/configuration you own rather than making reusable Prompts the long-term destination.
Step 3: choose conversation ownership
For each flow decide:
Durable provider-managed state?
→ Conversations
Short response chain?
→ previous_response_id
Strict application-owned history/control?
→ store context yourself and send required inputYou do not need one state strategy for every AI feature.
Step 4: port tool orchestration
Implement and test the explicit function-call loop.
Add:
- authorization
- validation
- maximum tool iterations
- timeouts
- retry policy
- idempotency for consequential actions
- structured logging
Step 5: recover only history you actually have
Map application-stored history into new conversations where continuity matters.
Keep a migration table so retries are safe:
legacy_thread_id
new_conversation_id
migration_status
last_attempt_at
errorStep 6: replay production-like fixtures
Since the old API is already unavailable, you cannot rely on live side-by-side execution against Assistants.
Use retained fixtures and expected outcomes:
input
expected policy behaviour
expected tool call or no tool call
expected structured fields
expected authorization resultEvaluate behaviour, not wording equality.
Step 7: deploy with observability
Monitor:
- Responses API error rate
- latency
- tool-call failure rate
- average tool iterations
- token usage
- conversation creation/reuse failures
- missing migrated history
- user fallbacks/escalations
Keep provider request IDs in structured logs where appropriate so production failures can be investigated.
A reference architecture after Assistants
A durable SaaS integration can look like:
Web / mobile client
↓
Application API
↓
Authentication + tenant authorization
↓
AI orchestration service
├── agent config from source control/config store
├── conversation mapping
├── tool authorization
├── retries / limits
└── observability
↓
OpenAI Responses API
↕
Conversations API
↓
Approved tools
├── CRM
├── billing
├── product database
└── knowledge retrievalThe important ownership boundary is clear:
OpenAI runs the model and supported AI primitives.
Your application owns business identity, authorization, configuration lifecycle and consequential actions.
That boundary makes the next API change much cheaper to absorb.
Should new OpenAI projects use Chat Completions or Responses?
For new agent-style integrations, OpenAI recommends the Responses API.
OpenAI originally introduced Responses as the future direction for applications that combine models with built-in tools and multi-step workflows. It supports direct instructions, tools and state-management options without the old Assistants/Threads/Runs lifecycle.
Chat Completions is a different API and should not be confused with the Assistants shutdown.
If your product already has a simple, stable Chat Completions integration and does not need Responses-specific capabilities, evaluate migration on its own merits rather than treating August 26 as its deadline.
The deadline applied to Assistants API, not every OpenAI API integration.
A migration acceptance checklist
Before calling the migration complete:
- □No production code calls Assistants/Threads/Runs endpoints.
- □Agent instructions/configuration have a deliberate long-term home.
- □The design does not accidentally depend on reusable Prompts past November 30, 2026.
- □New persistent chats use Conversations where appropriate.
- □Conversation IDs are mapped to authenticated application identities.
- □Tool schemas are current for Responses.
- □Tool execution is authorised independently of model output.
- □Consequential tools are idempotent where needed.
- □Historical context is migrated only from verifiable retained data.
- □Missing legacy history has an explicit product fallback.
- □Function-call loops have limits, retries and logs.
- □Token usage and latency are monitored after release.
- □Response retention and conversation retention choices match product policy.
- □Production fixtures cover expected AI behaviour and failure modes.
If several boxes remain open, the code may compile while the migration is still operationally incomplete.
FAQs
When did OpenAI shut down the Assistants API?
OpenAI officially sunset the Assistants API on August 26, 2026. Its current migration documentation states that the API is no longer available and recommends Responses API plus Conversations API.
What replaces an OpenAI Thread?
For durable server-side conversation state, the current replacement is the Conversations API. Conversations store a stream of items that can include messages, tool calls and tool outputs.
What replaces an OpenAI Run?
Runs are replaced by Responses. The Responses API handles model execution, while application code takes explicit responsibility for orchestration such as function-tool loops and retries.
Should I migrate an Assistant to a reusable Prompt object?
Not as an unexamined long-term design. OpenAI's migration guide maps Assistants to Prompts but also warns that reusable Prompt objects are deprecated. OpenAI schedules those objects and the __INLINE_CODE_0__ API to shut down on November 30, 2026 and recommends moving reusable prompt content into application code.
Can I still fetch old Thread messages after August 26?
OpenAI's current migration guide says the Assistants API call used to retrieve Thread messages no longer works and tells developers to use messages already stored by their application when preserving earlier history.
Do Responses retain conversation history forever?
Not exactly. OpenAI says normal Response objects are stored for 30 days by default, while Conversation objects and their items are not subject to that 30-day TTL. Choose the state model and your own retention policy deliberately.
Conclusion
The Assistants API migration is now a recovery and architecture task, not a deadline reminder.
The old stack is gone:
Assistants
Threads
Runs
Run stepsThe durable replacement is not simply another set of renamed OpenAI objects.
A safer long-term model is:
Application-owned configuration
↓
Responses API
↕
Conversations where durable state is needed
↓
Application-owned authorization and toolsThat design avoids two expensive mistakes: depending on an API that has already shut down, and moving directly onto reusable Prompt objects that OpenAI is also retiring on November 30, 2026.
If your SaaS, chatbot or AI workflow still needs to be moved from the old Assistants architecture, Softotic's AI and machine learning service can help redesign the agent and tool layer, while custom software development can handle the surrounding conversation, authorization and backend integration architecture.