<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Baran Yalçın</title>
    <description>The latest articles on DEV Community by Baran Yalçın (@baranyalcin).</description>
    <link>https://dev.to/baranyalcin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4075278%2Fd7baf58b-c91f-4587-aef4-5a54e52c6ae0.jpg</url>
      <title>DEV Community: Baran Yalçın</title>
      <link>https://dev.to/baranyalcin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/baranyalcin"/>
    <language>en</language>
    <item>
      <title>OpenAI Assistants API is deprecated. Here is what does not survive the migration.</title>
      <dc:creator>Baran Yalçın</dc:creator>
      <pubDate>Mon, 17 Aug 2026 13:03:06 +0000</pubDate>
      <link>https://dev.to/baranyalcin/openai-assistants-api-is-deprecated-here-is-what-does-not-survive-the-migration-ld</link>
      <guid>https://dev.to/baranyalcin/openai-assistants-api-is-deprecated-here-is-what-does-not-survive-the-migration-ld</guid>
      <description>&lt;p&gt;The OpenAI Assistants API shuts down on &lt;strong&gt;26 August 2026&lt;/strong&gt;. After that, &lt;code&gt;/v1/assistants&lt;/code&gt;, &lt;code&gt;/v1/threads&lt;/code&gt; and &lt;code&gt;/v1/threads/runs&lt;/code&gt; return errors. No grace period, no read-only mode.&lt;/p&gt;

&lt;p&gt;There are already good guides on the mechanical side: how &lt;code&gt;Assistant&lt;/code&gt; becomes a prompt, &lt;code&gt;Thread&lt;/code&gt; becomes a conversation, &lt;code&gt;Run&lt;/code&gt; becomes a response. This is the other half, the part the guides leave out. &lt;strong&gt;What you actually lose.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I build &lt;a href="https://glytos.com" rel="noopener noreferrer"&gt;Glytos&lt;/a&gt;, which imports OpenAI assistants, so I had to map the Assistant object field by field and decide, for every one, where it goes or whether it goes at all. This is what came out of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What transfers cleanly
&lt;/h2&gt;

&lt;p&gt;Pure configuration. Whatever you move to, these come with you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;instructions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model&lt;/code&gt;, &lt;code&gt;temperature&lt;/code&gt;, &lt;code&gt;top_p&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;response_format&lt;/code&gt;, including a strict &lt;code&gt;json_schema&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;your function tool definitions: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;parameters&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your assistant is a prompt plus a model plus a schema, you are in the easy case and you can stop reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does not
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The endpoint behind every function tool
&lt;/h3&gt;

&lt;p&gt;The one people underestimate, because the schema &lt;em&gt;does&lt;/em&gt; transfer and that feels like success.&lt;/p&gt;

&lt;p&gt;A function tool is two things. The schema, which tells the model the tool exists and what arguments it takes. And the implementation: the URL you call, the auth header, the timeout, the retry policy, the error mapping. Only the first lives in the Assistant object. The second has always lived in your code.&lt;/p&gt;

&lt;p&gt;So after the migration you have an agent that knows it can call &lt;code&gt;lookup_order&lt;/code&gt; and no idea how. Every tool gets rewired by hand. Fifteen tools is fifteen small integration jobs, and none of them appear on any migration checklist.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Your file_search content
&lt;/h3&gt;

&lt;p&gt;Worth being precise, because it depends where you are going.&lt;/p&gt;

&lt;p&gt;Vector stores are account-level objects. Move to the &lt;strong&gt;Responses API&lt;/strong&gt; and they survive: you stop attaching them through &lt;code&gt;tool_resources&lt;/code&gt; and start passing &lt;code&gt;vector_store_ids&lt;/code&gt; to the &lt;code&gt;file_search&lt;/code&gt; tool yourself. Annoying, not fatal.&lt;/p&gt;

&lt;p&gt;Move &lt;strong&gt;anywhere else&lt;/strong&gt; and you re-upload and re-chunk. That is not a byte-shuffling job. Different chunking, different embedding model, different retrieval defaults mean your agent gets different context for the same question. The files move. The answers may not.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. code_interpreter, conditionally
&lt;/h3&gt;

&lt;p&gt;Stay on the Responses API and it survives. It runs in a container, created automatically with &lt;code&gt;"container": {"type": "auto"}&lt;/code&gt; or explicitly through the &lt;code&gt;v1/containers&lt;/code&gt; endpoint.&lt;/p&gt;

&lt;p&gt;Go anywhere else and there is no equivalent unless that platform runs its own sandbox. That is a rewrite, not a migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that actually costs you time
&lt;/h2&gt;

&lt;p&gt;Not the state management everyone argues about in the threads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The configuration moves and the behaviour does not.&lt;/strong&gt; You can lift an assistant across in a minute, then spend two weeks working out why it answers differently, because retrieval shifted underneath it and nothing told you.&lt;/p&gt;

&lt;p&gt;If you have an evaluation set, run it before and after. If you do not, write down five questions your agent gets right today and check them by hand on the other side. Five is enough to catch the ugly surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do this part today
&lt;/h2&gt;

&lt;p&gt;Whatever you decide, get your definitions out while the API still answers. That configuration exists in exactly one place, and after the 26th there is nothing left to read it from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# The SDK paginates automatically as you iterate.
&lt;/span&gt;&lt;span class="n"&gt;assistants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_dump&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assistants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;assistants.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assistants&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;saved &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assistants&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; assistants&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it, commit the JSON, decide where it goes later. Retrieving them has a deadline. Choosing a destination does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this comes from
&lt;/h2&gt;

&lt;p&gt;Disclosure, since it is why I did this mapping at all: Glytos is a platform for voice and chat agents, and importing OpenAI assistants is one of the things it does.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbt0y9r57xpdeohf1t7s3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbt0y9r57xpdeohf1t7s3.gif" alt="Glytos Migration" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flow is: connect your OpenAI key, pick which assistants to bring, read the report. The key authorises the single request that lists your assistants and is never written to our database.&lt;/p&gt;

&lt;p&gt;Each assistant becomes an agent with its instructions, model settings and response format intact, strict json_schema included. Its function tools arrive as HTTP stubs, schema preserved, waiting for you to point each one at an endpoint.&lt;/p&gt;

&lt;p&gt;The report is the part that matters. It is essentially this article generated against your own account: which tools still need a URL, which assistants had files you will have to re-upload, which had a code_interpreter that did not come across.&lt;/p&gt;

&lt;p&gt;Two things it does not do. It does not bring your files, for the chunking reasons above. And the one-click path reads through OpenAI's API, so it stops working on the 26th along with everything else. After that it takes the JSON from the script above, which is the other reason to run that script today.&lt;/p&gt;

&lt;p&gt;None of this is required for the migration itself. The export script is four lines, and that is the part with a deadline.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>assistantapi</category>
    </item>
  </channel>
</rss>
