A row of weathered wooden stakes with pale bands stands in wet tidal sand at dusk, a lantern hanging from the nearest one, while driftwood and a small rowboat drift along curved currents
All posts

OpenAI GPT-4, o1, o3-mini and o4-mini shutdown on October 23, 2026: what breaks and what to check

OpenAI shuts down GPT-4, o1, o3-mini and o4-mini on October 23, 2026. Find hidden model IDs and check replacements for parameters, output and cost.

OpenAI shuts down gpt-3.5-turbo, gpt-4, gpt-4-turbo, o1, o3-mini, o4-mini, gpt-4.1-nano, gpt-image-1 and several fine-tuned models on 23 October 2026, according to its deprecations page. Any code path that still names those IDs, including retry fallbacks and scheduled jobs, stops working on that date. The migration is to find every place that names them, then check that the listed replacement (gpt-5.6-terra, gpt-5.6-sol or gpt-5.6-luna for the text models) accepts your parameters, produces acceptable output and fits your budget.

Whether to pin exact model IDs or follow aliases comes after the migration steps below. Pinning does not avoid migration: it replaces "whenever the alias is retargeted" with "the retirement date on the provider's schedule", which you can plan around.

Which OpenAI models are shut down on 23 October 2026?

OpenAI announced this wave on 22 April 2026. The table groups the models by the replacement the deprecations page recommends, as read on 2026-10-07. The page lists each snapshot together with its undated aliases and -completions variants.

OpenAI models with a shutdown date of 23 October 2026, grouped by listed replacement
Listed replacementModels shut down
gpt-5.6-terragpt-3.5-turbo, o4-mini, and the fine-tuned ft-gpt-3.5-turbo, ft-o4-mini-2025-04-16, ft-babbage-002 and ft-davinci-002
gpt-5.6-solgpt-4, gpt-4-1106-preview, gpt-4-turbo, gpt-4o-2024-05-13, o1, o3-mini and the fine-tuned ft-gpt-4
gpt-5.6-sol with reasoning.mode: proo1-pro
gpt-5.6-lunagpt-4.1-nano and the fine-tuned ft-gpt-4.1-nano-2025-04-14
gpt-image-2.5-sunburst or gpt-image-2.5-flaregpt-image-1

Two details change what you search for. The page lists the dated snapshot gpt-4o-2024-05-13, but not the undated gpt-4o, gpt-4o-mini or gpt-4.1, which are absent from the upcoming-deprecations list. And o3 is not part of this wave: its dated snapshot o3-2025-04-16 retires on 11 December.

Where do retired model IDs hide in your code?

Primary calls get migrated first. The breakage that survives that pass sits in code that runs rarely: retry and fallback lists, library and config defaults, eval and CI scripts, scheduled jobs, and fine-tuned model IDs stored in a database. A TheRouter summary of this wave tells readers to check primary models, fallback targets and per-team overrides. A Koenig AI Academy guide describes the failure: if a retry path still falls back to gpt-3.5-turbo, the primary model can be healthy while the fallback request fails. We did not reproduce that scenario. It follows from the shutdown and has not been measured.

This search finds the IDs in the table above, including dated snapshots and -completions variants:

rg -uu -nP '\b(?:gpt-3\.5-turbo(?:-0125)?|gpt-4(?:-0613|-1106-preview|-turbo(?:-2024-04-09)?)?|gpt-4\.1-nano(?:-2025-04-14)?|gpt-4o-2024-05-13|o1(?:-2024-12-17|-pro(?:-2025-03-19)?)?|o3-mini(?:-2025-01-31)?|o4-mini(?:-2025-04-16)?|gpt-image-1)(?:-completions)?(?![\w.-])|(?<=ft:)(?:babbage|davinci)-002(?![\w.-])' .

Against a 27-line sample, the pattern matched all 19 retiring IDs, including fine-tunes of babbage-002 and davinci-002, and none of the 8 control IDs that are not in the table, such as gpt-image-1.5. The -uu flags also search git-ignored and hidden files such as .env, and dependencies, so expect noise from lockfiles. A default you do not own, for example inside a library under node_modules, is fixed by passing the model explicitly at the call site. Then compare the hits with your request logs: the search finds IDs that exist, and the logs show which ones are still called.

What changes when you move to the replacement?

The listed replacements are not drop-in. Three of the retiring models are also in the AIVAX catalog, which we read on 2026-10-07 at https://inference.aivax.net/api/v1/information/models.json. For those, the catalog prices and the model definitions in the product code show a difference in price and in temperature support.

AIVAX list price per million tokens and temperature support, retiring model versus listed replacement
Retiring modelListed replacementInput / output, USD per 1M tokensFlagged as not supporting temperature
@openai/o4-mini@openai/gpt-5.6-terra0.825 / 3.30, then 2.20 / 13.20Yes, then yes
@openai/o3-mini@openai/gpt-5.6-sol0.825 / 3.30, then 4.40 / 22.00Yes, then yes
@openai/gpt-4.1-nano@openai/gpt-5.6-luna0.10 / 0.40, then 0.22 / 1.32No, then yes

These are AIVAX list prices, not OpenAI's, and the catalog marks gpt-5.6-sol as discounted, so that price can change; check the pricing page before you budget. Per-token price is also not cost per task. The catalog lists thinking capability for all three replacements and not for gpt-4.1-nano, so a move from nano to luna can change latency and token use as well as the price. Measure completed-task cost on your own requests, and see how reasoning effort differs across providers for the controls.

The temperature column comes from the model definitions in the product code; the public catalog does not expose it. It matters for gateways, because the AI Gateway docs warn that some integrated models reject temperature. If a gateway sets temperature on gpt-4.1-nano, expect to remove it when you move to gpt-5.6-luna and to re-qualify the output without it. We did not send a request to test this.

How do you check a replacement before 23 October?

Freeze a set of real requests and their accepted outputs before you touch anything, and run the candidate model against it. Compare the things that break quietly:

  • Parse and schema failures. If a parser or schema sits behind the call, see where structured-output healing stops before assuming the new model fails the same way.
  • Request parameters. Models differ in what they accept. Anthropic's page says a non-default temperature, top_p or top_k returns a 400 from Claude Opus 4.7 onward, and the AIVAX gateway docs note that some integrated models reject assistant prefill, temperature, stop sequences or reasoning effort.
  • Tool calls and multi-turn behavior. A single-turn comparison can miss a model that stops calling a tool several turns in. Agentic Tests run a simulated user and a judge against an AI Gateway, so create a second gateway with the replacement model and run the same scenarios against both. They complement a single-turn regression set and do not replace one; the Agentic Tests docs list the quotas that apply.
  • Latency and cost per completed task, not per token. A model that needs fewer retries can cost less per task at a higher token price. Our post on judging agent trajectories covers production signals for whole runs.

When the candidate passes, change the gateway or the pinned ID in one place, keep the old value in version control, and run the check again.

Which should you use: a pinned model ID or an alias?

With an alias, the provider (or a router) decides, and nothing in your code changes when it does. With an exact ID, the target stays fixed until the retirement date, and after it requests fail. Anthropic's deprecation page puts it plainly: requests to models past the retirement date will fail.

What each way of naming a model asks of you
NamingWho decides when behavior changesWhat you must doFits
Exact or dated IDYou, until the provider's retirement dateTrack the retirement date and run a replacement test before itParsers, budgets, customer-facing promises, regression baselines
Provider aliasThe provider, on its own scheduleDetect retargeting yourself; record what the alias resolved toPrototypes, internal helpers where a different answer costs little
Router alias (AIVAX @model-router/...)The platform, when it changes the alias targetRe-run your checks when the target changesTier-based choices where you accept movement within a tier
Gateway nameYou, by editing the gatewayQualify the new model before changing the gatewayMany clients that should switch together without a redeploy

An alias with a nightly check is a defensible middle path: the provider still decides, and you learn about the change sooner.

What do providers actually do with aliases and snapshots?

The rules differ by provider and change between model generations, so read the provider's page rather than inferring from the name.

  • Anthropic. For the 4.6 generation and later, the dateless ID is the canonical ID and maps to one fixed snapshot; Anthropic says it does not update the weights or configuration of an existing ID. For earlier models, a dateless alias such as claude-sonnet-4-5 points to the most recent dated snapshot of that minor version. Every ID, dated or not, has its own retirement schedule, and partner platforms such as Amazon Bedrock and Google Cloud set their own, so dates can differ there. See Model IDs and versioning and Model deprecations.
  • OpenAI. The December 2026 removals on the deprecations page are listed by dated snapshot, for example gpt-5-2025-08-07 and o3-2025-04-16. Check how the undated name behaves for your account before you rely on it.
  • Mistral. Its model lifecycle page warns that aliases switch to newer models automatically once they reach general availability, and recommends pinning a major.minor version for precise control.

A pinned ID is still subject to the provider's retirement date. Notice periods also differ: Anthropic promises at least 60 days for publicly released models, while OpenAI's page lists gpt-5.4-cyber as deprecated on 11 September 2026 and removed on 1 October, and gives six months for the April 2027 removals.

Which retirements come after 23 October?

These dates come from the official pages as read on 2026-10-07. Recheck them before you plan around them.

Announced retirements after 23 October 2026 from the providers' own pages, read on 2026-10-07
DateModelListed replacement
2026-11-30Anthropic claude-sonnet-4-5-20250929claude-sonnet-5-5
2026-12-01OpenAI gpt-image-1-mini, gpt-image-1.5 and chatgpt-image-latestgpt-image-2.5-sunburst or gpt-image-2.5-flare
2026-12-11OpenAI gpt-5-2025-08-07, gpt-5-mini-2025-08-07, gpt-5-nano-2025-08-07, gpt-5-pro-2025-10-06, o3-2025-04-16, o3-pro-2025-06-10gpt-5.6-sol, gpt-5.6-terra or gpt-5.6-luna, depending on the model
2027-01-06OpenAI tts-1, tts-1-hd and the gpt-4o-mini-tts snapshotsgpt-realtime-2.1-mini
2027-01-20OpenAI gpt-realtime, gpt-audio and their -mini and gpt-4o variantsgpt-realtime-2.1, gpt-realtime-2.1-mini or gpt-audio-1.5
2027-02-26OpenAI whisper-1 and the gpt-4o transcription modelsgpt-transcribe or gpt-live-transcribe
2027-04-01OpenAI gpt-5.3-codex, gpt-5.4-nano, gpt-5.1gpt-6-sol or gpt-6-luna

Two notes. Anthropic lists claude-haiku-4-5-20251001 as active, "not sooner than October 15, 2026", which is a floor and not a retirement notice. And Google's deprecations page, last updated 2026-10-07, lists gemini-2.5-flash, gemini-2.5-flash-lite and gemini-2.5-pro with no shutdown date announced; third-party summaries that give a date for them do not match the official page.

How do AIVAX aliases and gateways change the trade-off?

AIVAX offers three ways to name what runs: an integrated model ID such as @openai/gpt-6-sol, a router alias such as @model-router/openai:mid, and a gateway name. They sit at different points in the table above.

Router aliases move. The alias resolves to a concrete model, and the public changelog records these retargets. @model-router/openai:mid was pointed at GPT-6 Sol on 22 September and at GPT-6.1 Sol on 2 October; the 2 October entry also moved @model-router/claude:mid to Claude Sonnet 5.5. Each entry warns that applications using the aliases may see changes in response quality, latency and cost, and that existing explicit model identifiers remain unchanged. Our routing guide covers when tier aliases are worth that movement.

Explicit IDs do not move, but they can be flagged and retired. The catalog flags some models as deprecated. On 2026-10-07 it flagged @openai/o3-mini, @openai/o4-mini and @openai/gpt-4.1-nano, which are in the 23 October wave, and also @openai/o3, @openai/gpt-4.1, @openai/gpt-4.1-mini, @openai/gpt-4o and @openai/gpt-4o-mini, which are not on OpenAI's 23 October list. The flag is AIVAX's own signal, not a provider shutdown date. In the current implementation AIVAX can email an account that used a flagged model in the previous 30 days. The alert is enabled by default and debounced to once every seven days, but it is not described in the public docs, so check your account's notification settings before relying on it. Record the provider's shutdown dates separately, from the pages above.

A gateway is a place to make the change once. The AI Gateway docs describe a gateway as a persistent configuration that applications call by name, so its behavior can change without redeploying the caller. That makes it a natural switch: clients keep calling the gateway while you qualify and change the model behind it. Two limits apply. We found no documented automatic substitution when a model becomes unavailable, so treat an unavailable model as an error your application must handle. In the code, resolving a gateway whose model name is no longer in the catalog throws "Couldn't resolve the model name"; we did not run that case. The catalog and the provider's shutdown schedule are separate lists, so check both. And a gateway only moves the decision to you; you still own the replacement test.

How do you monitor alias targets and deprecation flags?

Keep a lock file of every integrated model ID and router alias your code or gateways use, plus the concrete model each router alias should resolve to. A CI job compares it with the live catalog. The catalog is served at https://inference.aivax.net/api/v1/information/models.json, and we called it without an API key on 2026-10-05 and again on 2026-10-07. We did not find this endpoint in the documentation, so treat its shape as unversioned. The script flags an entry when stability or flags is missing; it does not check that routingModel or isDeprecating exist, so a catalog that dropped them would pass silently.

{
  "@model-router/openai:mid": "@openai/gpt-6-sol",
  "@openai/gpt-6.1-sol": null,
  "@openai/o3": null,
  "@acme/retired-model": null
}
import { readFile } from "node:fs/promises";

const lock = JSON.parse(await readFile("models.lock.json", "utf8"));
const response = await fetch("https://inference.aivax.net/api/v1/information/models.json");
const { data } = await response.json();
const catalog = new Map(data.flatMap((group) => group.models).map((model) => [model.name, model]));

let failures = 0;

for (const [name, expectedTarget] of Object.entries(lock)) {
  const model = catalog.get(name);
  const problems = [];

  if (!model) {
    problems.push("not in catalog");
  } else {
    if (model.stability === undefined || model.flags === undefined) problems.push("unexpected catalog shape");
    if ([model.stability].flat().includes("Offline")) problems.push("offline");
    if (model.flags?.isDeprecating) problems.push("flagged as deprecating");
    if ((model.routingModel ?? null) !== expectedTarget) {
      problems.push(`resolves to ${model.routingModel ?? "nothing"}, expected ${expectedTarget ?? "nothing"}`);
    }
  }

  failures += problems.length > 0;
  console.log(`${problems.length ? "FAIL" : "ok  "} ${name}${problems.length ? ` (${problems.join("; ")})` : ""}`);
}

process.exit(failures ? 1 : 0);

Run with bun check-models.js on 2026-10-05, this deliberately stale lock produced:

FAIL @model-router/openai:mid (resolves to @openai/gpt-6.1-sol, expected @openai/gpt-6-sol)
ok   @openai/gpt-6.1-sol
FAIL @openai/o3 (flagged as deprecating)
FAIL @acme/retired-model (not in catalog)

The exit code was 1. The stability field arrives as an array, which is why the script flattens it. Run it nightly and before each deploy, and change the lock deliberately, in a pull request, when you accept a retarget. This lock format holds only model targets or null, so track retirement dates and owners separately, for example in a calendar or an inventory next to each model's owner. A retarget between two runs goes unnoticed until the next run.

Frequently asked questions

Which OpenAI models stop working on 23 October 2026?

Per OpenAI's deprecations page: gpt-3.5-turbo, gpt-4, gpt-4-turbo, gpt-4-1106-preview, gpt-4o-2024-05-13, gpt-4.1-nano, o1, o1-pro, o3-mini, o4-mini, gpt-image-1 and the fine-tuned ft-gpt-3.5-turbo, ft-gpt-4, ft-gpt-4.1-nano-2025-04-14, ft-o4-mini-2025-04-16, ft-babbage-002 and ft-davinci-002. The page does not list gpt-4o, gpt-4o-mini or gpt-4.1 in that wave.

Do fine-tuned models break too?

The page lists specific fine-tuned model families with the same date and a recommended replacement base model. To keep a fine-tuned model you would train it again on the replacement base and re-qualify the result; the page does not describe an automatic conversion.

Is a -latest alias ever safe in production?

When a changed answer is cheap, a human reads the output, and you record what the alias resolved to at the time. Use a fixed snapshot when accepting a new version requires regression testing.

Does pinning protect me from deprecation?

No. A fixed snapshot prevents alias retargeting, but it does not guarantee identical outputs or availability until retirement, and the retirement date becomes the date that matters. Anthropic and OpenAI both publish those dates, and notice periods differ.

What happens in AIVAX when a model I use is deprecated?

The catalog flag changes, and an account that used the model in the last 30 days can receive the email alert described above. We found no documented automatic substitution, so plan to change the model yourself.

Should I put the model name in application code or in a gateway?

Use a gateway when several clients must change together or when you want to switch without redeploying. Use an exact ID in code when one service owns its own behavior and tests. Either way, record the choice in the lock file.

Start with the 23 October table: search your repositories and gateways for those IDs, replace them one call at a time, and run the replacement checks above on each.