# OpenAI's October 23 shutdowns: find every call before it fails

URL: https://infro.io/blog/openai-model-shutdowns-october-2026
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-10-13
Last modified: 2026-10-13
Last reviewed: 2026-10-13 (next review due 2026-11-12)
Topic: Architecture and migration
Format: Guide

> On 23 October 2026 OpenAI's API stops serving o1, o1-pro, o3-mini, o4-mini, gpt-4o-2024-05-13, gpt-4-turbo, gpt-4-0613, gpt-4-1106-preview, gpt-4.1-nano, gpt-3.5-turbo-0125, gpt-image-1 and the legacy fine-tunes built on them; the listed replacements are gpt-5.6-sol, -terra and -luna and gpt-image-2.5-sunburst or -flare. Find callers from traffic first, then code, config and stored data; qualify the replacement with the parameters your code actually sends; put the model behind a name you control; and block the old ids before the date. Azure OpenAI deployments of the same models follow Microsoft's later dates.

Key takeaways:
- On 23 October 2026 OpenAI shuts down o1, o1-pro, o3-mini, o4-mini, gpt-4o-2024-05-13, gpt-4-turbo, gpt-4-0613, gpt-4-1106-preview, gpt-4.1-nano, gpt-3.5-turbo-0125, gpt-image-1 and six families of legacy fine-tunes.
- The aliases go with the snapshots: a request for `o4-mini` or `gpt-4-turbo` fails the same day as the dated id.
- Fine-tuned models on these bases stop too, and the listed replacement is a base model, so whatever the fine-tune learned has to be rebuilt with prompts or evaluation.
- Azure OpenAI retires the same models on its own schedule: o1, o3-mini and o4-mini on 19 November, gpt-4o 2024-05-13 on 9 December, gpt-image-1 on 23 October.
- Inventory from traffic first; code search misses ids in config, databases, queued jobs and library defaults.
- Check the parameters you send against the replacement's model page: gpt-5.6-sol and -terra list reasoning effort as none, low, medium, high, xhigh and max, with medium the default.

OpenAI announced on 22 April 2026 that a set of legacy model snapshots would be shut down on 23 October 2026[1]. Six months of notice is generous, and it is easy to spend it. If anything in your systems still calls `o4-mini`, `o3-mini`, `o1`, `gpt-4-turbo` or `gpt-image-1`, it has ten days left.

This guide covers that one date: exactly what goes, what OpenAI names as each replacement, what the change looks like to a running request, and how to find and move every caller in the time left. The general method for any retirement, from evaluation to weighted canary, is in the [model deprecation migration playbook](https://infro.io/blog/model-deprecation-migration-playbook); this article does not repeat it.

## What OpenAI shuts down on 23 October

OpenAI's deprecations page groups these under "Legacy GPT model snapshots", announced 2026-04-22[1]. The table below is that section, with the aliases OpenAI lists next to each snapshot.

| Snapshot | Aliases that go with it | Listed replacement |
| --- | --- | --- |
| `o1-2024-12-17` | `o1` | `gpt-5.6-sol` |
| `o1-pro-2025-03-19` | `o1-pro` | `gpt-5.6-sol` with `reasoning.mode: pro` |
| `o3-mini-2025-01-31` | `o3-mini` | `gpt-5.6-sol` |
| `o4-mini-2025-04-16` | `o4-mini` | `gpt-5.6-terra` |
| `gpt-4o-2024-05-13` | none | `gpt-5.6-sol` |
| `gpt-4-turbo` | `gpt-4-turbo-2024-04-09`, `gpt-4-turbo-completions` | `gpt-5.6-sol` |
| `gpt-4-0613` | `gpt-4`, `gpt-4-0613-completions`, `gpt-4-completions` | `gpt-5.6-sol` |
| `gpt-4-1106-preview` | none | `gpt-5.6-sol` |
| `gpt-4.1-nano` | `gpt-4.1-nano-2025-04-14` | `gpt-5.6-luna` |
| `gpt-3.5-turbo-0125` | `gpt-3.5-turbo`, `gpt-3.5-turbo-completions` | `gpt-5.6-terra` |
| `gpt-image-1` | none | `gpt-image-2.5-sunburst` or `gpt-image-2.5-flare` |

Table: OpenAI's 23 October 2026 shutdowns, from the deprecations page read 2026-10-13.

The same section removes fine-tuned models built on these bases: `ft-gpt-4`, `ft-gpt-3.5-turbo`, `ft-o4-mini-2025-04-16`, `ft-gpt-4.1-nano-2025-04-14`, `ft-babbage-002` and `ft-davinci-002`. Their listed replacements are base models — `gpt-5.6-sol`, `-terra` or `-luna` — not new fine-tunes[1].

[Diagram: Every model id that stops answering on OpenAI's API on 23 October 2026, with the replacement OpenAI lists. Read from the deprecations page on 2026-10-13.]

Three details in that list catch teams out.

**The aliases go too.** `o4-mini`, `o3-mini`, `o1`, `gpt-4` and `gpt-3.5-turbo` are not moving to a newer snapshot; they are listed as retiring with the snapshot they point at[1]. Code that used an alias precisely to avoid snapshot churn breaks on the same day as code that pinned the date.

**Only one gpt-4o snapshot goes.** The entry is `gpt-4o-2024-05-13`, the first gpt-4o snapshot. Nothing in the 22 April section names the bare `gpt-4o` alias, so check which id each caller actually sends before you treat "gpt-4o" as affected or safe.

**gpt-image-1 is a different job.** Its replacements are image models with a different quality range: OpenAI's image guide says the 2.5 models add `xhigh` and `max` quality, while earlier GPT Image models support quality settings up to `high`; it documents three recommended sizes plus custom dimensions in multiples of 16 for the 2.5 models[2]. An image pipeline needs its own test pass, not just a renamed model.

## What a shutdown means for a request

OpenAI's definitions are short: a model announced as deprecated "immediately becomes deprecated", and at shutdown "the model or endpoint will no longer be accessible"[1]. The page describes no grace period and no automatic upgrade on OpenAI's own API. The page does not document the exact error body a retired id returns, so do not write a handler that matches one string. Treat any error on a request that names a retired id as a deployment defect, and alert on it.

Fine-tuned models follow their base. OpenAI's note on fine-tuning says inference on fine-tuned models continues "until the base models are deprecated"[1] — and on 23 October these bases are. A separate entry adds that from 6 January 2027 active existing customers can no longer create new self-serve fine-tuning jobs[1]. If a fine-tune carried behaviour that prompting has not reproduced, plan for prompts, examples or evaluation work now, because a new fine-tune is not on the listed path.

### Azure and aggregators keep their own dates

A model served through another platform retires on that platform's schedule. Microsoft's retirement schedule for Azure OpenAI, updated 2026-09-23, lists o1, o1-pro, o3, o3-mini, o3-pro and o4-mini for 19 November 2026, gpt-4o version 2024-05-13 for 9 December 2026, gpt-4.1-nano for 14 April 2027, and gpt-image-1 (a preview there) for 23 October 2026[3].

[Diagram: The same model, retired on different dates. OpenAI's dates from its deprecations page; Azure's from Microsoft's model retirement schedule, both read 2026-10-13.]

Azure also behaves differently after the date. A retired model returns `410 Gone`, Standard deployments can be upgraded automatically to the named replacement depending on the deployment's `versionUpgradeOption`, and provisioned deployments are not auto-upgraded[4]. A team running the same app against both OpenAI and Azure can see one half break on 23 October and the other half silently change model in December.

Aggregators are less explicit. OpenRouter's o4-mini page carried no shutdown notice when read on 2026-10-13[5]. That is not a promise of continued service: an aggregator can serve a model only while some upstream it uses still does. If an aggregator is in your path, ask it which upstream serves each retiring id after 23 October, and test.

## Find every caller

Most teams know where their main application calls OpenAI. The calls that fail on the date are the ones nobody lists: a nightly summarizer, an eval harness, a support macro, a customer-specific model setting saved in a table three years ago.

[Diagram: Where retiring model ids hide. Traffic shows what was actually sent; the other two columns explain who sent it and catch callers that run rarely.]

### Start from traffic

What was actually sent is the only complete inventory of callers that ran. Pull 30 days of requests grouped by model and by API key from whatever records them: the provider's usage export, your gateway or proxy logs, or your own request logging. Group by the id as sent, not a normalised family name, so `o4-mini` and `o4-mini-2025-04-16` show up as what they are. For each key that sent a retiring id, find the owning service and its owner. A key nobody can name is a finding in itself.

Thirty days misses monthly jobs and anything that runs on demand. That is what the next two passes are for.

### Then search code and configuration

Search every repository, including infrastructure and notebooks, for the literal ids. Anchor the pattern so `o1` does not match every version string:

```bash
# Literal model ids retiring on 2026-10-23, quoted in code, config or YAML.
rg -n --hidden -g '!node_modules' -g '!*.lock' \
  -e '["'"'"'`](o1|o1-pro|o3-mini|o4-mini|gpt-4|gpt-4-turbo|gpt-4-0613|gpt-4-1106-preview|gpt-4o-2024-05-13|gpt-4\.1-nano|gpt-3\.5-turbo|gpt-image-1)(-[0-9-]+)?(-completions)?["'"'"'`]' \
  -e 'ft[:-](gpt-4|gpt-3\.5-turbo|o4-mini|gpt-4\.1-nano|babbage-002|davinci-002)'
```

Then look where ids are not literals: environment variables and secret stores (`OPENAI_MODEL`, `LLM_MODEL`, per-environment overrides), feature-flag and remote-config systems, Helm values and Terraform variables, fallback lists inside retry wrappers, and defaults in the libraries and frameworks you call through. A wrapper that falls back to `gpt-3.5-turbo` when the primary fails will pass every test until the day the primary has an outage.

### Then the data

Products that let users or operators choose a model store that choice. Query every table that holds prompt templates, agent definitions, workspace settings or per-customer model overrides:

```sql
-- Adjust table and column names; run against every store that keeps model choices.
SELECT model, count(*) AS rows, max(updated_at) AS last_changed
FROM prompt_configs
WHERE model ~ '^(o1|o1-pro|o3-mini|o4-mini|gpt-4|gpt-4-turbo|gpt-4o-2024-05-13|gpt-4\.1-nano|gpt-3\.5-turbo|gpt-image-1)($|-)'
   OR model LIKE 'ft:%'
GROUP BY model
ORDER BY rows DESC;
```

Check queues and schedulers too: a job enqueued on 20 October with a model id in its payload runs after the date with the old id.

## What changes when you swap the model

Changing the model string is the smallest part of the migration. The replacements are a different generation, and the request your code sends was written for the old one. Check these against the replacement's own page, not against memory.

**Reasoning effort.** OpenAI's reasoning guide says supported effort values are model-dependent, from `none` through `max`, and that GPT-5.6 defaults to `medium` when you omit `reasoning.effort`[6]. The `gpt-5.6-sol` and `gpt-5.6-terra` pages list `none`, `low`, `medium`, `high`, `xhigh` and `max`[7][8]. If your o-series code sends a value that is not on that list, find out what the replacement does with it before the date, not after.

**Pro mode.** `o1-pro` maps to `gpt-5.6-sol` with `reasoning.mode: pro`[1]. The guide warns that pro mode "performs more model work than standard mode, increasing token usage and cost"[6]. Budget for it per request, not per model.

**Output limits include reasoning.** `max_output_tokens` limits everything the model generates, reasoning tokens and visible output together, and reasoning tokens are billed as output[6]. A limit tuned for gpt-4-turbo's visible output can truncate a reasoning model's answer. Watch the share of responses that stop on length after the switch.

**Context and price shape.** Both `gpt-5.6-sol` and `gpt-5.6-terra` list a 1,050,000-token context window with up to 922,000 input tokens and 128,000 output tokens. Sol lists $4 input, $0.40 cached input and $20 output per million tokens; Terra lists $2, $0.20 and $12. On both, prompts over 272K input tokens cost twice the input rate and 1.5 times the output rate for the whole request[7][8]. Compute cost per completed task on recorded traffic; per-token rates alone do not tell you what a task costs once reasoning length changes.

**Endpoints.** The Terra page lists Chat Completions, Responses and Batch and marks Realtime, Assistants, Embeddings and Audio as unsupported[8]. The `-completions` aliases in the shutdown table are a reminder that some callers still use the legacy text completions shape. Those callers need a request rewrite, not a rename.

> **Example: What a reasoning-length change does to cost per task**
> Suppose a ticket-summary job sends 3,000 input tokens and gets 400 visible output tokens per ticket on its old model. On `gpt-5.6-terra` at the listed $2 input and $12 output per million, with no reasoning, that is $0.006 + $0.0048 = $0.0108 per ticket. If the default `medium` effort adds 1,200 reasoning tokens, billed as output, the same ticket costs $0.006 + $0.0192 = $0.0252. The token counts are hypothetical; measure yours on recorded requests, and set effort explicitly rather than inheriting a default.

## A ten-day cut-over plan

[Diagram: A suggested schedule for the days left before 23 October. The order matters more than the dates: inventory before anything else, block before the provider does.]

- [ ] **Day 1: inventory.** Thirty days of traffic by model id and key, then code, config and stored-data searches. One owner per caller.
- [ ] **Days 2–5: qualify.** Run the listed replacement on a few hundred recorded requests per workload with the exact parameters your code sends. Compare task success, refusals, truncation, output and reasoning tokens, and cost per completed task.
- [ ] **Days 3–6: indirect.** Move callers from a hard-coded model id to a name you control — a config key, an alias in your client wrapper, or a gateway route — so the next retirement is a configuration change.
- [ ] **Days 5–8: shift.** Move traffic in stages and keep the old model as a fallback only until the last stage; a fallback to a model that is about to disappear protects nothing.
- [ ] **Day 8: block.** Make your own systems refuse the retiring ids, so a caller you missed fails in staging or in your logs with a clear message, while you can still fix it.
- [ ] **23 October onward: watch.** Alert on any request that still names a retired id, on errors by model, and on the model id each response reports. Diary the Azure dates if you run there too.

The playbook covers the qualify and shift steps in depth, including a weighted canary; see [when a provider retires a model](https://infro.io/blog/model-deprecation-migration-playbook).

## Finding and moving callers with INFRO

INFRO is a control plane that sits between your applications and the provider accounts you already hold. You connect your own OpenAI account, OpenAI bills you directly, and INFRO records each request that passes through it. For a retirement, four parts of it apply. All four work only on traffic that goes through INFRO; calls made straight to OpenAI do not appear.

**Who still calls a model.** `GET /v1/usage` groups requests, errors and estimated provider cost by `model`, `project`, `key`, `route` and more, and `GET /v1/requests` filters by `model`, `project` and `key`, with `route=none` selecting direct model calls rather than route traffic. `GET /v1/requests/export` returns the same rows as CSV. The window is bounded by the plan's request history: 7 days on Developer, 14 on Startup, 30 on Team and 90 on Business. See [usage analytics](https://infro.io/docs/observability/analytics) and [request history](https://infro.io/docs/observability/traces).

**Stop new usage.** A [model allowlist](https://infro.io/docs/org/model-allowlists) at organization, project or key level can block a model with a `!` entry, such as `!openai/gpt-image-1`. A blocked model is refused with `403` and code `model_not_allowed`, naming the list that refused it, before any provider is called. Route targets and fallbacks remain subject to the same policy.

**Change the model without a deploy.** An application can name a [route](https://infro.io/docs/routes), for example `"model": "ticket-summary"`, instead of a model id. The route resolves to targets on your own connections, and editing its targets changes which model serves with no code change. A weighted route with the new model as a zero-weight standby is how the shift step above is done in the console.

**Notices and drift.** When INFRO deprecates a model in its catalog, the notice appears under the bell in the console and is emailed to owners and admins, with the retirement date, the successor and what in your organization still uses it: requests in the last 30 days, the keys that sent it or allow it by name, and the routes that target it. After cut-over, [traffic changes](https://infro.io/docs/observability/traffic-changes) raise a `traffic.model_changed` finding when a connection starts being answered by a model id it had not reported in the previous 14 days.

One limit to state plainly: of the models on OpenAI's 23 October list, INFRO's model catalog carries `openai/gpt-image-1`. The o-series and GPT-4 era snapshots are not catalog models, so a request through INFRO cannot name them on an OpenAI connection; it is answered `404 model_not_found`. Whether any model answers at all is decided by OpenAI, on your account.

## Sources

1. Deprecations — OpenAI. https://developers.openai.com/api/docs/deprecations (accessed 2026-10-13)
2. Image generation — OpenAI. https://developers.openai.com/api/docs/guides/image-generation (accessed 2026-10-13)
3. Model retirement schedule — Microsoft. https://learn.microsoft.com/en-us/azure/foundry/openai/concepts/model-retirement-schedule (accessed 2026-10-13)
4. Foundry Models lifecycle and support policy — Microsoft. https://learn.microsoft.com/en-us/azure/ai-foundry/openai/concepts/model-retirements (accessed 2026-10-13)
5. o4-mini model page — OpenRouter. https://openrouter.ai/openai/o4-mini (accessed 2026-10-13)
6. Reasoning models — OpenAI. https://developers.openai.com/api/docs/guides/reasoning (accessed 2026-10-13)
7. GPT-5.6 Sol model page — OpenAI. https://developers.openai.com/api/docs/models/gpt-5.6-sol (accessed 2026-10-13)
8. GPT-5.6 Terra model page — OpenAI. https://developers.openai.com/api/docs/models/gpt-5.6-terra (accessed 2026-10-13)
