- Book: Ship It — the pragmatic startup tech stack
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
If the model string in your code starts with gpt-4o or gpt-4.1, it has an expiry date now. On October 14, 2026, OpenAI's deprecations page added an entry that reads: "On October 14, 2026, we notified developers using certain GPT-4 series models of their deprecation", with removal from the API on January 14, 2027.
That is 92 days from notice to shutdown. The replacement OpenAI names for every model on the list is gpt-6-luna.
If you shipped a classifier, an extractor or a support-ticket router on a small OpenAI model in the last two years, check which one. The small call behind a feature nobody has touched since launch keeps working until January 14. Then it stops.
What's on the list
The October 14 entry has four rows, all with the same shutdown date and the same replacement:
| Model | Snapshot IDs | Replacement |
|---|---|---|
| GPT-4o |
gpt-4o-2024-08-06, gpt-4o-2024-11-20
|
gpt-6-luna |
| GPT-4o mini | gpt-4o-mini-2024-07-18 |
gpt-6-luna |
| GPT-4.1 | gpt-4.1-2025-04-14 |
gpt-6-luna |
| GPT-4.1 mini | gpt-4.1-mini-2025-04-14 |
gpt-6-luna |
The entry adds one more sentence that matters if you trained anything: "Fine-tuned versions of these models follow the same shutdown schedule as their underlying base models." So a fine-tuned 4o mini goes dark on the same day.
The table lists dated snapshots, not the bare gpt-4o alias. The GPT-4o model page names gpt-4o-2024-08-06 as its default snapshot, and that snapshot is on the list. Don't assume the alias outlives it. Check the exact ID you call; the grep and API check below find it.
Two GPT-4 series snapshots were already on their way out before this notice. The same page lists gpt-4o-2024-05-13 and gpt-4.1-nano for shutdown on October 23, 2026, from an April 22 notice. If you pinned either of those, your deadline is nine days away, not 92.
The legacy GPT-4o audio and realtime models are not in this entry. They have their own dates, starting January 20, 2027.
Three months' notice, under a policy that lists six
The deprecations page has a section on notice periods. For generally available models it says: "At least 6 months." Specialized variants of those models get "At least 3 months." Preview models "may be retired with much shorter notice, such as 2 weeks." The whole list is introduced with "Unless safety or compliance concerns require a faster timeline", and in that case OpenAI says it "will provide as much notice as reasonably possible" (OpenAI).
October 14 to January 14 is three months. The October 14 entry doesn't say which category these snapshots fall under, and it gives no reason for the timeline. It doesn't link a migration guide either.
Compare the entry right below it. On October 1, OpenAI gave gpt-5.1 and gpt-5.3-codex a shutdown date of April 1, 2027, six months out, so the newer models got twice the runway (OpenAI).
If you run these models through Azure, your dates are not OpenAI's. Microsoft's model retirement schedule lists all five of these snapshots as retiring on April 14, 2027, and it keeps fine-tuned deployments running longer: until October 1, 2027 for gpt-4o and gpt-4o-mini, and until October 14, 2027 for gpt-4.1 and gpt-4.1-mini. That page was last updated in late September, before OpenAI's notice, so watch it for changes.
What changes when you move to gpt-6-luna
On price per token, Luna is cheaper than everything it replaces. From OpenAI's pricing page, Standard tier, per million tokens:
| Model | Input | Output |
|---|---|---|
gpt-4o |
$2.50 | $10.00 |
gpt-4.1 |
$2.00 | $8.00 |
gpt-4.1-mini |
$0.40 | $1.60 |
gpt-4o-mini |
$0.15 | $0.60 |
gpt-6-luna |
$0.10 | $0.50 |
Per token is not per task, though. Three things on the Luna model page change how your existing calls behave:
-
It reasons by default. Reasoning is on at
mediumeffort unless you setreasoning.effort. The levels run fromnonetomax. A 4o mini classifier answered straight away. Luna at its default effort thinks first. -
Tools prefer the Responses API. On Chat Completions, function calling works only when reasoning effort is
none. For built-in tools, use the Responses API. - No fine-tuning. Luna doesn't support it. If your production model is a fine-tuned 4o mini, there is no fine-tuned Luna to move it to. OpenAI has restricted new fine-tuning jobs since May 2026, and existing customers lose the ability to create them on January 6, 2027.
Long prompts cost more too. Above 272K input tokens, Luna charges 2x for input and 1.5x for output, on the whole request (OpenAI).
For a fast, cheap call that used to go to 4o mini, the closest like-for-like starting point is Luna with reasoning off, through the OpenAI Node SDK:
import OpenAI from "openai";
const client = new OpenAI();
const res = await client.responses.create({
model: "gpt-6-luna",
reasoning: { effort: "none" },
input: "Label this ticket: refund not received",
});
console.log(res.output_text);
Then run your eval set against it before you flip the switch. I haven't run Luna against a 4o mini workload myself, and OpenAI's notice makes no quality claim about the swap. If you have no eval set, the 92 days are the time to build one.
Find every call before January does
Start with your own code. git grep searches tracked files only, so it usually skips node_modules and build output:
git grep -nE "gpt-4(o|\.1)"
That pattern also matches the audio, realtime, TTS and transcribe variants and the two snapshots from the April notice, which have different dates, so read the hits rather than counting them. Then check the places grep can't see: environment variables, config services, feature flags and database rows that hold a model name.
Then ask the API. OpenAI says the List models endpoint now carries an optional shutdown_date field: "When present, this field contains the shutdown date as a YYYY-MM-DD string", or null if none is announced (OpenAI). With jq, this prints every model on your account that has one, soonest first:
curl -s https://api.openai.com/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY" \
| jq -r '.data[]
| select(.shutdown_date != null)
| "\(.shutdown_date) \(.id)"' \
| sort
Fail the build before the API does
The same field is also on the Retrieve a model endpoint (OpenAI), so a few lines of shell can fail a pipeline when the model you deploy with has a shutdown date:
#!/usr/bin/env bash
# Fail CI when the model we call has a shutdown date.
set -euo pipefail
model="${OPENAI_MODEL:?set OPENAI_MODEL}"
url="https://api.openai.com/v1/models/$model"
shutdown=$(curl -sSf "$url" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
| jq -r '.shutdown_date // empty')
if [ -n "$shutdown" ]; then
echo "::error::$model shuts down on $shutdown"
exit 1
fi
echo "$model: no shutdown date announced"
The ::error:: prefix is a GitHub Actions workflow command that shows up as an annotation on the run. Once the model is gone, curl -f fails on the error response and the script exits non-zero anyway. Set OPENAI_MODEL to the dated snapshot rather than the alias, since the deprecation table lists snapshots, or the check can pass on a model that is about to go.
Failing on any announced date is strict on purpose: your team hears about the next deprecation from a red build instead of an archived email. If that is too loud, compare the date against a window and only fail inside it.
Treat the model ID like a runtime version or a database engine, a dependency with a lifecycle you don't control. Keep it in one place in config, and keep an eval set that tells you in an afternoon whether the replacement holds up.
If this was useful
A model shutdown is one of those production chores nobody plans for until a vendor sets the date. Ship It is my book on everything between localhost and production for a small team: hosting, deploys, payments, auth, CI/CD and monitoring, so checks like the one above have somewhere to live.
I also build Hermes IDE, a free, source-available IDE that runs Claude Code, Codex and other command-line agents side by side, each in its own terminal and worktree, on macOS, Windows and Linux. Weigh that with the fact that it's mine. Download it or star it on GitHub.

Top comments (0)