◉CLAUDE LABJP
●CODE 2.1.319 — Claude Code now moves MCP tasks to the background automatically, and a denyInsteadOfPrompting setting denies calls that would wait on a prompt●CONSOLE — Console IP allowlist is in beta (11/5): requests from addresses not on the list are refused●SONNET 4.5 — Retires on the Claude API on 11/30, 22 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST — Opus 4.8 fast mode is deprecated and will be removed on 11/30. Migrate to Opus 5.5●NEW — I Put a Ten-Line Promise File at the To…●CODE 2.1.319 — Claude Code now moves MCP tasks to the background automatically, and a denyInsteadOfPrompting setting denies calls that would wait on a prompt●CONSOLE — Console IP allowlist is in beta (11/5): requests from addresses not on the list are refused●SONNET 4.5 — Retires on the Claude API on 11/30, 22 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST — Opus 4.8 fast mode is deprecated and will be removed on 11/30. Migrate to Opus 5.5●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-11-09Beginner

Does an Undated claude-sonnet-4-5 Escape the November 30 Retirement?

The retirement table lists only the dated Sonnet 4.5 ID. Here is how I read the docs to decide whether the undated alias stops too, and the one grep that catches both.

Claude API145Model DeprecationSonnet 4.54Model IDsAliases

I was counting the lines that mention claude-sonnet-4-5 across my own code samples and notes when something odd came up.

The retirement table lists claude-sonnet-4-5-20250929, with a date attached. But most of what I had written down was the undated form. The count was 69 places without a date and 61 with one.

My first thought was that I'd never typed the date, so the table's "November 30" probably wasn't about me. I wasn't sure that thought would survive a second look, so I went back to the docs. Here is what I found.

The table only lists the dated ID

On the model deprecations page, the relevant rows read like this today.

API model nameCurrent stateDeprecatedTentative retirement date
claude-sonnet-4-5-20250929DeprecatedSeptember 30, 2026November 30, 2026
claude-sonnet-4-6ActiveN/ANot sooner than February 17, 2027

The recommended replacement is claude-sonnet-5-5. There is no row for the undated claude-sonnet-4-5, which makes "not listed, so not affected" a tempting reading. That reading was my mistake.

An undated ID can be an alias for the latest dated one

The "Model IDs and versioning" page gets closer to an answer. For models before the 4.6 generation, the Claude API also accepts shorter aliases. claude-sonnet-4-5, for example, points to the most recent dated snapshot of that minor version.

So claude-sonnet-4-5 isn't a separate model. It's a shortcut to claude-sonnet-4-5-20250929. The same page also says every model ID has its own deprecation and retirement schedule.

Here is how I sorted it out.

What you wroteWhat the docs sayRelation to November 30
claude-sonnet-4-5-20250929A dated snapshotThe row in the table. Affected
claude-sonnet-4-5An alias for the latest dated snapshotIt points at 20250929, so it is natural to expect it to stop the same day
claude-sonnet-4-6Undated, but not an alias. It is the snapshot itselfA different ID. The table gives February 17, 2027 as the earliest date

The "stops the same day" part is my own inference from how aliases work. I haven't seen the docs say it in one sentence. So I decided to treat the alias as affected rather than bet that it's exempt.

One more trap: from the 4.6 generation on, an undated ID such as claude-sonnet-4-6 is not an alias. The docs say plainly that it is a pinned snapshot, not an evergreen pointer that moves to newer versions. Having no date doesn't mean being newer.

One grep for both forms

If you search only for the dated string, aliases slip through. A single pattern covers everything.

# Dated, undated, and the Bedrock / Google Cloud spellings in one pass
grep -rnE --exclude-dir=node_modules --exclude-dir=.git \
  'claude-sonnet-4-5(-20250929|@20250929|-v1:0)?' .

On Amazon Bedrock the ID appears as anthropic.claude-sonnet-4-5-20250929-v1:0, and on Google Cloud (Google managed) as claude-sonnet-4-5@20250929. The pattern above catches all three. Note that those partner platforms set their own retirement schedules, so the November 30 date in the table applies to the platforms Anthropic operates. Keep that boundary in mind.

Then sort the hits into config files and prose. Only the lines that actually send requests can break anything.

If you're unsure, let the response tell you

You can see what an alias resolves to by sending one small request. The model field of the response carries the resolved ID.

import anthropic
 
client = anthropic.Anthropic()  # reads ANTHROPIC_API_KEY from the environment
msg = client.messages.create(
    model="claude-sonnet-4-5",  # send the alias
    max_tokens=16,
    messages=[{"role": "user", "content": "Reply with ok"}],
)
print(msg.model)  # the resolved ID shows up here

If a dated ID comes back, you know where the alias points. I decided to run this once before touching anything.

One thing to settle before you replace anything

Before rewriting every hit mechanically, separate the lines that really send requests. Grep alone can miss callers. I wrote up a way to count them from the Usage CSV in 43 Days Until Sonnet 4.5 Retires: I Counted Callers From the Usage CSV, Not From grep. And if you plan a bulk replace, Read the Catalog Your CLI Already Ships Before Bulk-Replacing Model IDs covers the step before it.

Count by the ID a name resolves to, not by whether it carries a date. That's the line I'm drawing this time.

Run the grep above once today and just count the undated lines. About three weeks remain, and once you have the number, the rest of the plan tends to fall into place.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ API & SDK2026-10-18
43 Days Until Sonnet 4.5 Retires: I Counted Callers From the Usage CSV, Not From grep
claude-sonnet-4-5 retires on November 30. grep only shows what is written in code. Here is a single script that cross-checks model IDs in your code against the Console's Usage CSV, with the results from running it.
⬡ API & SDK2026-11-07
Your Key Is Valid but You Get a 400 or 401 — Check the Workspace Header and Browser Calls Before Reissuing
When a Claude API key is valid but requests still fail with 400 or 401, two causes are worth ruling out before you create a new key: a missing workspace ID header and a direct call from the browser. A triage table and a small script you can run are included.
⬡ API & SDK2026-11-05
Three Changes I Made Before Moving to Message Threads, So My Own Copy of the Conversation Stays Mine
What changes when a loop that resends the full history every turn moves to message threads, which entered beta on November 2. How create and continue differ, how to triage a 404 or 400, and where I would not migrate, all based on the official docs.