skip to content

Sonnet

The workhorse Claude tier — the default balance of capability, speed and price for production traffic. Like Opus, it is a pointer here; the tier comparison itself lives under Claude model tiers.

on this pageshow

questions

3

In the Anthropic API, what model string identifies Claude Sonnet, and does it take a date suffix?

level: juniorimportance: must knowfreq 68%

answer

  1. the string you paste into model
  2. no calendar date in it
  3. each generation is its own string
  4. claude-sonnet-5, complete as written

basics

~10 s

Current Claude Sonnet models are called by undated alias strings such as claude-sonnet-5 and claude-sonnet-4-6. The ID is complete as written; appending a -YYYYMMDD snapshot suffix produces an unknown model and the request fails.

solid answer

~40 s

You pass the model ID in the top-level `model` field, and for the current Sonnet line that ID is a plain, undated string — `claude-sonnet-5` for the newest, `claude-sonnet-4-6` for the previous generation. A very common mistake is bolting a date on the end (`claude-sonnet-5-20260101`); those dated-snapshot IDs belonged to older Claude generations and are not how current models are addressed, so the API rejects the string as an unknown model. Because each generation ships under its own string, pinning a version is simply a matter of not editing that string — an existing ID never silently becomes the next generation. If you need to enumerate what is actually callable, hit the Models API (`GET /v1/models`, or `client.models.list()` / `client.models.retrieve(id)`), which returns `id`, `display_name`, `created_at`, `max_input_tokens`, `max_tokens` and `capabilities` per model.

code

python · 6 lines
python
from anthropic import Anthropic

client = Anthropic()

for model in client.models.list():
    print(model.id, model.display_name, model.max_input_tokens, model.max_tokens)

go deeper

for a junior

Know that the model goes in a top-level model field as one exact string, and that current Sonnet IDs like claude-sonnet-5 carry no date. If a call fails with an unknown-model error, check the string before anything else.

for a middle

Be able to explain that each generation is published under its own ID, so pinning means not editing the string, and that the Models API is where you read a model's real context window and output cap rather than hardcoding numbers.

for a senior

Show that you keep the model ID in one configuration point, treat an upgrade as a change requiring a regression pass because parameter support differs between generations, and handle platform-specific ID forms explicitly per backend.

for a principal

Own the policy: who is allowed to bump a model string, how a new generation is canaried against real traffic before it becomes the default, and how you avoid a fleet where every service pins a different Sonnet generation with no owner.

## Where the ID goes Every Anthropic Messages API request carries a top-level `model` field holding a single string. There is no separate "family" and "version" field, no `provider` field, and no wildcard: the one string fully determines which weights serve the request, what the context window is, and what request parameters are legal. Getting that string wrong is the single most common first-request failure, and it surfaces as a 404-style `not_found_error` naming the model rather than anything that hints at the real problem. ## The current Sonnet strings are undated aliases For the Sonnet tier as of mid-2026, the callable IDs are `claude-sonnet-5` (current) and `claude-sonnet-4-6` (the previous generation, still available). Both are complete as written. There is no `-latest` suffix to append, no `@` version separator on the first-party API, and no date component. This trips people who learned the API during the era when Claude models were addressed by dated snapshots — strings that ended in a release date. That convention still shows up in older code and in some platform-specific IDs, which is exactly why the muscle memory persists. On the first-party API today, adding a date is not "more specific", it is simply wrong: the server has no such model registered and the call fails before any tokens are billed. ## Aliases versus snapshots, and what "pinning" means here With dated snapshots, pinning meant choosing the dated string so a floating alias could not move under you. With the current naming, each generation is published under its own distinct string — `claude-sonnet-4-6` and `claude-sonnet-5` are different models, not two views of one moving target. So the pin is the string itself: a deployment naming `claude-sonnet-4-6` keeps getting 4.6 behaviour until a human edits the config. Upgrading is a deliberate one-line change, and it is a real change — successive Sonnet generations differ in which request parameters they accept and in some response defaults, so an upgrade deserves a test pass rather than a blind swap. ## Discovering IDs and capabilities at runtime Hardcoding a model string is fine for a service you deploy, but tools that present a model picker should read the list rather than ship a stale array. The Models API gives you that: `client.models.list()` auto-paginates over the models your key can call, and `client.models.retrieve("claude-sonnet-5")` fetches one. Each object carries `id` (the exact string to pass back as `model`), `display_name` (human-facing), `created_at`, `max_input_tokens` (the context window), `max_tokens` (the output cap) and `capabilities`. Note the field name for the window: there is no `context_window` field, and code that reaches for one gets `None`/`undefined` rather than an error, which then quietly breaks token-budget arithmetic downstream. ## Platform variations The same model reached through a cloud partner is not addressed by the same string. On Amazon Bedrock, Claude model IDs take an `anthropic.` prefix (for example `anthropic.claude-opus-5`). On Google Vertex AI, current-generation models use the bare first-party ID, while the older dated-snapshot models use an `@` separator between name and date rather than a hyphen. Copying a Bedrock-shaped ID into a first-party client — or the reverse — is a routine cause of "model not found" in multi-cloud codebases, so the model string belongs next to the client construction in configuration, not scattered through call sites. ## Practical rules Keep the ID in one place, typed or constant, so an upgrade is a single edit. Never build the string by concatenating a family name and a date at runtime. Treat a `not_found_error` mentioning the model as a string problem first — key, region and prefix second. And if you support several backends, store the full platform-specific ID per backend rather than trying to derive one from another.

  • How do you pin a Sonnet version so a new generation cannot change your behaviour under you?
    You pin by choosing the exact ID string and leaving it alone. A new generation is published under a different string, so `claude-sonnet-4-6` never becomes `claude-sonnet-5` on its own. Keep the ID in one config constant, and treat changing it as a code change that gets a regression pass, since parameter support and some response defaults differ between generations.
  • How would you discover a model's context window and capabilities at runtime instead of hardcoding them?
    Call the Models API — `client.models.list()` to enumerate, `client.models.retrieve(id)` for one. Each object exposes `id`, `display_name`, `created_at`, `max_input_tokens` (the context window), `max_tokens` (the output cap) and `capabilities`. There is no `context_window` field, so code reading that name silently gets nothing.
  • Does the model string change when you call Claude Sonnet through a cloud partner?
    Yes. Amazon Bedrock prefixes Claude IDs with `anthropic.`, while Google Vertex AI uses the bare first-party ID for current-generation models and an `@` separator for older dated snapshots. Store the full platform-specific ID per backend rather than deriving one from another, and use each platform's dedicated client class instead of pointing the first-party client at a different base URL.

saying these in an interview costs you the question

  • Assumes every Claude model ID needs a -YYYYMMDD snapshot suffix
  • Thinks appending -latest gives you the newest Sonnet
  • Sends a Bedrock anthropic.-prefixed ID to the first-party API
  • Believes one alias silently upgrades from 4.6 to 5
  • Reads a context_window field off the Models API response

context

open as a page

Which sampling parameters does claude-sonnet-5 reject, and what controls reasoning depth instead?

level: middleimportance: should knowfreq 52%

basics

~10 s

claude-sonnet-5 removed temperature, top_p and top_k — sending any of them returns a 400. The fixed thinking budget (budget_tokens) is gone too. Depth and token spend are set with output_config.effort, alongside adaptive thinking.

open as a page

After moving a streaming app to claude-sonnet-5, thinking blocks arrive empty — why?

level: seniorimportance: should knowfreq 32%

basics

~20 s

On claude-sonnet-5 the thinking parameter's display field defaults to omitted, so thinking blocks stream with empty text. The previous generation defaulted to summarized. Set thinking to {"type": "adaptive", "display": "summarized"} to get readable reasoning back.

open as a page