Guide · OpenAI

OpenAI models retiring Oct 23, 2026: what to switch to

On October 23, 2026, OpenAI shuts down a large group of older models, including gpt-3.5-turbo, gpt-4, gpt-4-turbo, o1, o3-mini and o4-mini. Requests that name them start failing that day. Here is the full list, the replacement OpenAI names for each, and how to change your code safely.

OpenAI announced these retirements on April 22, 2026, on its deprecations page, which is linked at the end. This is not an SDK change: your openai package can be fully up to date and still send a model name that no longer exists. The fix is small for each call, but model names hide in many places (code, config files, environment variables, deployment manifests), and a new model can answer differently from the old one. The steps below cover finding every reference, choosing the replacement, and checking that your feature still behaves.

What changed

  • gpt-3.5-turbo, gpt-3.5-turbo-0125, o4-mini and o4-mini-2025-04-16 are retired. OpenAI's replacement is gpt-5.6-terra.
  • gpt-4, gpt-4-0613, gpt-4-turbo, gpt-4-turbo-2024-04-09, gpt-4o-2024-05-13, o1, o1-2024-12-17, o3-mini and o3-mini-2025-01-31 are retired. OpenAI's replacement is gpt-5.6-sol.
  • o1-pro and o1-pro-2025-03-19 are retired. OpenAI's replacement is gpt-5.6-sol with reasoning.mode: pro.
  • gpt-4.1-nano and gpt-4.1-nano-2025-04-14 are retired. OpenAI's replacement is gpt-5.6-luna.
  • gpt-image-1 is retired. OpenAI's replacement is gpt-image-2.5-sunburst or gpt-image-2.5-flare.
  • OpenAI also lists -completions variants of several of these names, such as gpt-3.5-turbo-completions and gpt-4-completions, with the same date.

Migration steps

  1. Make a list of every model name you use

    Start with an inventory, not with edits. Search the whole repository, including configuration and infrastructure files, for the retiring names. The plain-text search below is deliberately broad; the next section shows a structural search for SDK calls.

    rg -n --hidden -g '!node_modules' -g '!*.lock' \
      -e 'gpt-3\.5-turbo' -e 'gpt-4(-0613|-turbo)?["\x27]' -e 'gpt-4o-2024-05-13' \
      -e '["\x27]o1(-pro)?["\x27-]' -e 'o3-mini' -e 'o4-mini' -e 'gpt-4\.1-nano' -e 'gpt-image-1["\x27]'

    Look beyond source files. Model names often live in .env files, config.py or settings.ts, Helm charts, render.yaml or vercel.json, CI variables and your secrets manager. A name that comes from an environment variable will not show up in a code search at all, so check where each model= argument gets its value.

  2. Map each old name to its replacement

    Use the replacement OpenAI names for each model, listed under What changed. Put the mapping in one place so the next retirement is a one-line change. A small table in your settings module works well, and it also makes the change easy to review.

    Before

    # Model names scattered across the codebase
    reply = client.chat.completions.create(model="gpt-3.5-turbo", messages=messages)
    summary = client.chat.completions.create(model="gpt-4", messages=summary_messages)

    After

    # settings.py: one place to change model names
    CHAT_MODEL = os.environ.get("CHAT_MODEL", "gpt-5.6-terra")      # was gpt-3.5-turbo
    SUMMARY_MODEL = os.environ.get("SUMMARY_MODEL", "gpt-5.6-sol")  # was gpt-4
    
    reply = client.chat.completions.create(model=CHAT_MODEL, messages=messages)
    summary = client.chat.completions.create(model=SUMMARY_MODEL, messages=summary_messages)
    Python. Reading the name from settings, with a default, also lets you switch back quickly if a test shows a problem.

    Before

    const reply = await client.chat.completions.create({ model: "gpt-4-turbo", messages });

    After

    // models.ts
    export const CHAT_MODEL = process.env.CHAT_MODEL ?? "gpt-5.6-sol"; // was gpt-4-turbo
    
    const reply = await client.chat.completions.create({ model: CHAT_MODEL, messages });
    TypeScript, the same idea.
  3. Check what else the call depends on

    Changing the name is the easy part. Before you ship, read the replacement model's page in OpenAI's docs and compare it with how each call is written today. Check the parameters you pass, the token limits you rely on, any tool or structured-output settings, and the price per token, since the new model can cost more or less than the old one.

    • Calls that set sampling or token-limit parameters: confirm the replacement accepts them as written.
    • Code that parses the reply, such as JSON extraction or regular expressions: a different model can format answers differently.
    • Prompts tuned for the old model: they usually still work, but test the ones that matter most.
    • Budgets and rate limits: check pricing and limits for the replacement before you switch all traffic.
  4. Ship before the date, behind a switch

    Because the name now comes from settings, you can deploy the code change first and switch the model by changing one variable. Move a small share of traffic or one internal feature first, watch errors and output quality for a day, then switch the rest. Finish well before October 23 so there is time to react if something looks wrong.

How to find every affected call

The text search finds names. To find every API call and see which model argument each one receives, use ast-grep, which matches code structure instead of text:

sg run --pattern 'client.chat.completions.create($$$ARGS)' --lang python
sg run --pattern 'client.chat.completions.create($$$ARGS)' --lang typescript
sg run --pattern 'client.responses.create($$$ARGS)' --lang python

For each result, follow the model argument back to where its value is set. Calls that pass a variable are the ones a text search misses. You can also paste a public repository into the model retirement check, which lists every retiring model ID with its file and line, including LiteLLM and OpenRouter spellings such as openai/gpt-4.

Testing the change

Run your existing test suite first; it catches calls that fail outright. Then compare behavior, because a successful call can still give a different answer. Save the inputs and outputs of a few representative requests on the old model now, while it still works, and run the same inputs on the replacement.

  1. Pick 10 to 20 real inputs per feature, including tricky ones.
  2. Record the old model's outputs before October 23.
  3. Run the same inputs on the replacement and compare: format, length, refusals and correctness.
  4. Check cost and latency on the same inputs.
  5. Fix prompts or parsing where the new answers differ in ways that matter.

Automating it

OpenAI does not provide a codemod for model retirements, because the change depends on your configuration and your prompts. To catch the next retirement early, add the free Versyka GitHub Action to your repository. It comments on pull requests that add or keep a retiring model, with the date and replacement. The retirement calendar lists every announced date and has a calendar feed.

Versyka can also make the change for you: it finds every affected call, updates the model names and configuration, runs your tests, and opens a pull request for you to review.

Was this guide helpful?

Check your own repository

Paste your package.json, requirements.txt or pyproject.toml into the free upgrade check to see which API SDKs are behind, with no account. Or let Versyka run this migration on one repository and open a pull request that has already passed your tests.

Sources