# The migration, piece by piece
## The steps
1. Inventory every assistant: its instructions, model, and tool declarations. Each assistant becomes a prompt: recreate the instruction plus tool bundle as a named prompt in the dashboard, where prompts are versioned like code.
2. Store the prompt id in source control and point your code at it. Prompt ids can be swapped for A/B tests without creating or deleting API objects, which is the main operational win.
3. Migrate thread history to conversations. Threads held message streams; conversations hold streams of items (messages, tool calls, outputs). Export stored thread messages from your own records, since the old thread retrieval endpoints no longer work.
4. Replace runs with responses. A run was a managed execution; a response is a single model turn. Your application now owns the loop: send input, get output items, execute tool calls, send results back, repeat until done.
5. Move file search attachments to vector stores referenced by the file_search tool on the Responses API. Vector store ids carry over; the wiring around them changes.
6. Test the tool loop explicitly. The most common migration bug is a tool-call loop that never terminates or drops tool results, because the old runs endpoint managed that loop for you.
## The trap
Assuming it is a mechanical rename. The conceptual shift is who owns orchestration: the old API owned it, the new one hands it to you. Code that does not implement the tool loop will silently return unexecuted tool calls as final answers.
## Checklist
- Every assistant has a dashboard prompt with a stored prompt id.
- Thread history migrated from your own stored messages.
- The application implements the tool-call loop with a termination condition.
- Vector stores re-wired through the file_search tool.
- Tool-heavy flows tested end to end, not just single turns.