Anthropic Python SDK v1.0: What Breaks and How to Migrate Anthropic released the Python SDK v1.0 on August 20, 2026, moving the HTTP layer to httpx2, requiring Python 3.10+, and removing long-deprecated features including the legacy Text Completions API and sampling parameters from Messages methods. The SDK removal of temperature, top_p, and top_k coincides with seven current Claude models rejecting any non-default sampling value with a 400 error, while the Messages API still accepts them via extra_body on older models. Teams on Python 3.9 must pin anthropic==0.125.0, and the Bedrock client now raises an error at startup if no AWS region is configured. The Anthropic Python SDK v1.0 landed on August 20, 2026, and the release-notes entry https://platform.claude.com/docs/en/release-notes/overview is blunt about what it is: the HTTP layer moves from httpx to httpx2, the package now requires Python 3.10 or later, and a set of long-deprecated surface is removed outright — the legacy Text Completions API, the temperature , top p and top k parameters on Messages methods, and the tool runner’s client-side compaction control . The easy compression of that list is “Anthropic removed sampling controls.” It did not. The Messages API reference still documents and accepts all three parameters, and the SDK ships a documented workaround. What actually changed is one layer deeper: seven current Claude models reject any non-default sampling value with a 400 regardless of how the request reaches them. The SDK removal lands alongside that model-level rule, and the workaround only buys you anything on older models. That distinction is the whole story, and this guide leads with it. Below: what shipped and what did not this is Python only , the sampling split by model, a migration matrix with before-and-after code for every breaking change in the SDK’s own MIGRATION.md https://github.com/anthropics/anthropic-sdk-python/blob/main/MIGRATION.md , the one change that can break a running agent loop with nothing raised, the instrumentation that quietly stops seeing your Anthropic calls alongside it, the Bedrock construction that now fails at startup instead, and a real hold-back pin for teams that cannot move today. - 01This is a Python-only event.anthropic 1.0.0 was uploaded to PyPI on August 20, 2026 and the v1.0.0 GitHub tag was published the same day. The TypeScript SDK’s GitHub Releases show v0.120.0 Aug 19 as newest with no v1.0.0 tag. The last 0.x Python release, v0.125.0, went out on August 19 and is the hold-back pin. - 02httpx2 is a maintained, API-compatible fork — not an official successor.Anthropic’s release notes and SDK docs both use fork language. httpx2 is stewarded by Pydantic Services Inc. Build custom http client, Timeout and transport objects from httpx2, and call httpx2.alias httpx at startup if tracing or mocking libraries patch httpx directly. - 03Sampling parameters left the SDK signatures, not the API.temperature, top p and top k are gone from messages.create , messages.stream and messages.parse . The Messages API reference still accepts them, and extra body is the documented path. But seven current models return a 400 on any non-default value, thinking on or off, so extra body only helps on older models. - 04Two changes fail quietly; the Bedrock one fails at startup.Tool-runner compaction moved from a client-side kwarg to a server-side beta context management with betas= 'compact-2026-01-12' , trigger at 50,000 input tokens or more — a loop that simply drops the old argument keeps running and raises nothing. The httpx2 move is the other quiet one: tracing and mocking libraries that patch httpx by module name keep patching a module the SDK no longer uses unless you call alias httpx . AnthropicBedrock is the loud one — it now raises an error when no AWS region is configured instead of silently using us-east-1, so it announces itself the moment the client is constructed. - 05The floor is Python 3.10, and the 0.x line is your only 3.9 path.PyPI metadata for anthropic 1.0.0 lists Requires-Python =3.10 with classifiers for 3.10 through 3.14. If a service is stuck on 3.9, pin anthropic==0.125.0 or anthropic =0.125,<1 and schedule the runtime upgrade before the SDK upgrade. 01 — What ShippedA 1.0 that is a deprecation gate , not a feature drop. The v1.0.0 tag on anthropic-sdk-python https://github.com/anthropics/anthropic-sdk-python/releases was published on August 20, 2026 at 19:58 UTC, and its Conventional-Commits body is almost comically short: a single BREAKING CHANGES line pointing at the httpx2 upgrade and “some minor breaking changes,” a bug fix that stops the helpers warning about output format= , and a chore restoring the original streaming-event imports. Everything of substance lives in MIGRATION.md, which the release notes name as the canonical source “for every change with before-and-after snippets.” Read the timing alongside the last 0.x release and the shape of the event becomes clear. v0.125.0 went out on August 19 at 22:00 UTC — less than a day earlier — carrying managed-agents web-search configuration and self-hosted-sandbox memory-store support, none of it migration-related. v1.0 adds no comparable capability. It is the moment Anthropic chose to cash in a backlog of deprecations at once, which is exactly what a major version is for under the SemVer policy in Anthropic’s own Python SDK docs https://platform.claude.com/docs/en/cli-sdks-libraries/sdks/python : the package “generally follows SemVer,” with the caveat that some backward-incompatible type-only or internal changes may ship as minor versions. Three scope notes matter before you touch anything. First, this is the Python anthropic package only. The TypeScript SDK’s GitHub Releases https://github.com/anthropics/anthropic-sdk-typescript/releases show v0.120.0 August 19 as the newest entry and no v1.0.0 tag exists there. Second, it is separate from the Aug-19 wave that moved computer use, browser use, the Files API, Agent Skills and Admin API user management to GA — our post on that GA wave covers it /blog/claude-platform-betas-ga-computer-use-files-skills and nothing in it is restated here. Third, this is not Claude Code, which has its own changelog and version line. Up from 3.9 PyPI metadata for anthropic 1.0.0 lists Requires-Python =3.10, with classifiers for Python 3.10, 3.11, 3.12, 3.13 and 3.14 — five supported minors. The 0.x line remains the only path for 3.9 services. Last 0.x release Published August 19 at 22:00 UTC, under 24 hours before v1.0.0. Still installable from PyPI. Pin it if you cannot migrate today, and treat the pin as a dated exception with an owner. Optional extras on 1.0.0 aiohttp, aws, bedrock, google-cloud, mcp, vertex and webhooks. The base package still ships five platform client classes, including the AnthropicBedrock class whose region behaviour changed. Anthropic’s own install line for the new major is pip install --upgrade "anthropic =1,<2" . The upper bound is the point: it lets you take future 1.x releases without being carried into a future 2.0 by a loose constraint. The rest of this post assumes you are deciding whether to run that command this week or pin and schedule it. 02 — SDK vs APISampling parameters: the decisive distinction. Here is the sentence that is easiest to get wrong. MIGRATION.md removes temperature , top p and top k from the typed method signatures of messages.create , messages.stream and messages.parse . The Messages API reference https://platform.claude.com/docs/en/api/messages still lists all three as optional number fields with full descriptions — defaults, ranges, the nucleus-sampling explanation. Nothing on that page says they were removed from the API. The SDK dropped the parameters; the wire protocol did not. The documented escape hatch is extra body , and MIGRATION.md gives the before-and-after itself: Before 0.x : typed keyword argument message = client.messages.create model=MODEL, max tokens=1024, temperature=0.2, messages= {"role": "user", "content": "Summarise this contract."} , After 1.x : pass it through to the request body message = client.messages.create model=MODEL, max tokens=1024, extra body={"temperature": 0.2}, messages= {"role": "user", "content": "Summarise this contract."} , So far, an SDK-only story, and the release notes give it a one-line rationale: v1.0 “removes long-deprecated surface.” What makes it more than a signature change sits in a different document entirely. The Thinking docs https://platform.claude.com/docs/en/build-with-claude/thinking ’ “Limits and feature compatibility” section — evergreen reference documentation describing the current model line, not an August 20 announcement — states the model-level rule that makes the workaround moot for most production traffic: Put the two documents together and the picture is exact. Seven current models hard-reject any non-default sampling value, through the SDK, through raw HTTP, with thinking on or off. On those models, extra body={"temperature": 0.2} produces the same 400 the typed argument would have. There, the SDK removal takes away nothing the API would have honoured — the typed surface and the model behaviour now agree. extra body exists for the older models where sampling is still honoured, and for default values everywhere. The table below is that rule extracted into something you can scan. | Model | temperature | top p | top k | Non-default value sent | |---|---|---|---|---| | Current models · hard 400, thinking on or off | |||| | Claude Fable 5 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Mythos 5 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Mythos Preview | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Opus 5 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Opus 4.8 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Opus 4.7 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Claude Sonnet 5 | Default only | Default only | Default only | 400 error on every request, regardless of transport or thinking state | | Older models · restriction applies only while thinking is on | |||| | Older models, thinking on | Incompatible with thinking | Allowed between 0.95 and 1 | Incompatible with thinking | temperature / top k rejected; top p accepted only inside the 0.95–1 band | | Older models, thinking off | Accepted as documented | Accepted as documented | Accepted as documented | Honoured per the Messages API reference — reach it via extra body in SDK 1.x | The practical consequence for a migration: grep your codebase for the three parameter names before you upgrade, and sort each hit by the model it targets. Hits against the seven current models were already failing or were sitting at default values — delete them. Hits against older models move to extra body , with a comment naming the model dependency, because the moment that call is repointed at a current model it becomes a 400 in production. Teams that went through our Opus 4.6 to 4.7 migration playbook /blog/claude-opus-4-6-to-4-7-migration-playbook-breaking-changes-2026 will recognise the shape: the model boundary, not the SDK boundary, is where sampling assumptions break. 03 — Migration MatrixEvery breaking change, with its scope and its fallback. MIGRATION.md documents each change but never says whether it is confined to the SDK or reflects something at the API or model layer. That column is the synthesis this table adds. “SDK-only” means a raw HTTP caller is unaffected; “SDK + model” means the behaviour you hit is enforced below the SDK; “client to server” means a capability moved rather than disappeared; “SDK client removed” means the typed wrapper is gone and MIGRATION.md does not state what the underlying endpoint does. The last column is the minimum action if you pin to 0.125.0 instead of migrating. | What broke | Scope | Before 0.x | After 1.x | If you pin to 0.125.0 | |---|---|---|---|---| | Transport and runtime | |||| | HTTP layer | SDK-only | import httpx | import httpx2 as httpx or httpx2.alias httpx at startup | Nothing now; audit every lib that patches httpx respx, pytest-httpx, OpenTelemetry, Sentry before you migrate | | Python floor | SDK-only | Python = 3.9 | Python = 3.10 | Pin is the only 3.9 path; schedule the runtime upgrade first | | Transport / proxy types | SDK-only | anthropic.Transport anthropic.ProxiesTypes | httpx2.BaseTransport httpx2.Proxy | Find-and-replace when you migrate; no runtime risk before | | Removed surface | |||| | Text Completions | SDK client removed | client.completions.create ... HUMAN PROMPT / AI PROMPT | client.messages.create ... | Highest-pressure item: port to Messages now, migrate SDK after | | temperature / top p / top k | SDK + model | messages.create ..., temperature=0.2 | messages.create ..., extra body={"temperature": 0.2} — older models only | Seven current models already 400 on non-default values; delete or default those calls regardless of SDK version | | output format schema dict | SDK-only | output format=SCHEMA DICT | output config={"format": SCHEMA DICT} helpers take types only for output format= | Move dict schemas to output config ahead of time; types keep working | | messages.parse stream=True | SDK-only never worked | messages.parse ..., stream=True | messages.stream ..., output format=Type stream.get final message .parsed output | None — MIGRATION.md says it crashed on 0.x too | | isinstance obj, Stream shim | SDK-only | isinstance obj, Stream | from anthropic.lib.streaming import MessageStream isinstance obj, MessageStream | Switch the check early; MessageStream is the right type on both lines | | Raw HTTP body= bytes | SDK-only | client.post ..., body=b"..." | client.post ..., content=b"..." | Rename when you migrate | | Behaviour changes | |||| | Tool-runner compaction | Client to server | compaction control={"enabled": True, "context token threshold": 100 000} | betas= "compact-2026-01-12" , context management={"edits": ... } trigger = 50,000 input tokens | Re-test any long agent loop on the server-side path before migrating; this one fails quietly | | AnthropicBedrock region | SDK-only | AnthropicBedrock silently used us-east-1 | AnthropicBedrock aws region="..." or AWS REGION / AWS DEFAULT REGION / boto3 profile | Set the region explicitly today — it documents the intent and is a no-op on 0.x | | Bedrock unknown stream events | SDK-only | amazon-bedrock-invocationMetrics yielded | Unknown events skipped, not yielded | If you read invocation metrics off the raw stream, that consumer needs a new source | | Async raw responses | SDK-only | response.parse response.text / response.content | await response.parse response.text / response.read | Wrap raw-response access in one helper so the await lands in one place | | HTTP headers | SDK-only | Case-sensitive names; bytes values tolerated | Case-insensitive names; bytes values raise | Decode header values to str now | | Renames | |||| | Type aliases | SDK-only | BetaBase64PDFBlockParam agent toolset.READ MAX BYTES | BetaRequestDocumentBlockParam agent toolset.DEFAULT MAX FILE BYTES | Rename when you migrate | Fifteen rows, and only one of them — sampling — is enforced at the model layer. One more, compaction, moved to a server-side beta rather than vanishing. That ratio is the reassuring part of the release. It also tells you where to spend review time: the “Behaviour changes” rows deserve a test each, and so does the HTTP-layer row, because the changes that fail quietly give you nothing to grep for, while the renames and the removed-surface rows announce themselves at import or at the first call. The sections below take them in turn. 04 — Transporthttpx to httpx2: a fork with careful wording. MIGRATION.md explains the transport move in one line: the SDK’s HTTP layer moved from httpx, “which is no longer actively maintained,” to httpx2. The httpx2 project on PyPI https://pypi.org/project/httpx2/ is stewarded by Pydantic Services Inc., whose pydantic/httpx2 repository https://github.com/pydantic/httpx2 hosts the fork, with original-author continuity from Tom Christie, httpx’s creator, and its current release at the time the SDK shipped was 2.12.0 from August 18 — two days earlier. The PyPI description is explicit about the motive: “With HTTPX itself seeing limited activity recently, Pydantic is picking up stewardship under the HTTPX2 name so that users have a reliably maintained path forward — including timely security updates.” Notice what Anthropic does not say. Neither the release notes nor the SDK docs call httpx2 “the official successor” or claim an endorsement from the httpx maintainers. The release notes say “a maintained, API-compatible fork”; the SDK docs page, in its “Configuring the HTTP client” section, independently says “an API-compatible fork of httpx.” Neither phrase carries an endorsement, and that restraint is the accurate version — it is the one to repeat in your change ticket. "The SDK sends requests with httpx2, an API-compatible fork of httpx."— Claude Platform docs, Python SDK page, “Configuring the HTTP client” For most codebases the change is invisible, because the default client is built for you and the DefaultHttpxClient helpers are unchanged. You have work to do in two situations: you construct your own http client , Timeout or transport objects from httpx, or you run tracing or mocking libraries that patch httpx by module name. python Before 0.x : custom client built from httpx import httpx from anthropic import Anthropic client = Anthropic http client=httpx.Client proxy="http://proxy.internal:3128" , timeout=httpx.Timeout 60.0 , After 1.x , option A: build the same objects from httpx2 import httpx2 as httpx from anthropic import Anthropic client = Anthropic http client=httpx.Client proxy="http://proxy.internal:3128" , timeout=httpx.Timeout 60.0 , After 1.x , option B: make plain import httpx resolve to httpx2. Call this once at process startup, before any library imports httpx. import httpx2 httpx2.alias httpx Option B is the one that matters for observability and test suites. MIGRATION.md names the category — libraries that patch httpx directly — and the usual suspects are respx , pytest-httpx , OpenTelemetry’s HTTPXClientInstrumentor and Sentry’s httpx integration. Without the alias, those tools keep instrumenting a module the SDK no longer uses, and the failure mode is silent: tests pass against a mock that never fires, traces stop showing Anthropic spans, and nobody gets an exception. Put httpx2.alias httpx in the same bootstrap that configures tracing, and add one test that asserts an Anthropic call appears in your span exporter. aiohttp as an opt-in alternative via DefaultAioHttpClient for higher async concurrency, and that path did not change in v1.0. If you already run on aiohttp, the httpx2 move touches you only where you import httpx types directly — check your type hints and test fixtures, not your request path . 05 — Removed SurfaceText Completions and the 3.10 floor. The loudest removal is the legacy Text Completions client. client.completions.create — the SDK’s wrapper for the /v1/complete endpoint — is gone, and so are the anthropic.HUMAN PROMPT and anthropic.AI PROMPT constants that built its prompt strings. Any module that still imports them fails at import time on 1.x, which at least makes this the easiest break to find. The fix is the port to Messages that has been the documented path for a long time. python Before 0.x : legacy Text Completions from anthropic import AI PROMPT, HUMAN PROMPT, Anthropic client = Anthropic completion = client.completions.create model=MODEL, max tokens to sample=300, prompt=f"{HUMAN PROMPT} Summarise this contract.{AI PROMPT}", text = completion.completion After 1.x : Messages from anthropic import Anthropic client = Anthropic message = client.messages.create model=MODEL, max tokens=300, messages= {"role": "user", "content": "Summarise this contract."} , text = message.content 0 .text The Python floor is the quieter removal, and the one with the longest lead time. MIGRATION.md states it plainly — “The minimum supported Python version has increased from 3.9 to 3.10” — and PyPI’s metadata for anthropic 1.0.0 https://pypi.org/project/anthropic/1.0.0/ confirms it independently with Requires-Python: =3.10 and classifiers for 3.10 through 3.14 only. A pip resolver on a 3.9 interpreter will simply refuse to select 1.0.0, which is polite, but it also means a service that pins anthropic loosely on 3.9 will stay on 0.x forever without telling anyone. Add an explicit upper bound so the intention is visible in the lockfile. Upgrade now For services already on Python 3.10+, on Messages, with no custom httpx objects and no client-side compaction. Run the test suite, check tracing spans, ship. Pin, then schedule For services on Python 3.9, still calling completions.create , or depending on client-side compaction control. The pin is the last 0.x release and stays installable; give it an owner and a date. Automated edit pass MIGRATION.md notes that Claude Code users can run this command for automated edits. Treat the output as a first draft — it is a helper for the SDK migration, not part of the SDK, and the review burden stays with you. 06 — Tool RunnerCompaction moved server-side ; it did not disappear. This is the change most likely to break a running agent loop without raising anything. On 0.x, the tool runner accepted a client-side compaction control argument that compacted context locally once a token threshold was crossed. On 1.x that argument is removed, and the replacement is the server-side context management feature behind the compact-2026-01-12 beta. Same job, different layer, and one new constraint: MIGRATION.md notes the trigger threshold must be at least 50,000 tokens. Before 0.x : client-side compaction runner = client.beta.messages.tool runner model=MODEL, max tokens=4096, tools=TOOLS, messages=history, compaction control={"enabled": True, "context token threshold": 100 000}, After 1.x : server-side context management beta runner = client.beta.messages.tool runner model=MODEL, max tokens=4096, tools=TOOLS, messages=history, betas= "compact-2026-01-12" , context management={ "edits": { "type": "compact 20260112", "trigger": {"type": "input tokens", "value": 100 000}, } }, Why it fails quietly: a loop that relied on local compaction and simply drops the argument keeps running, keeps accumulating context, and only surfaces a problem when it hits a context limit or a cost alarm many turns later. Two checks catch it. First, an integration test that drives a loop past the old threshold and asserts the compaction edit appears in the response. Second, a config lint that refuses any trigger value below 50,000 — the floor is documented, and a threshold copied over from an old client-side config can sit below it, which was fine locally and is rejected server-side now. If your agent loop lives in the Claude Agent SDK rather than in the Python SDK’s tool runner, this section does not apply to you directly — the Agent SDK has its own migration playbook /blog/claude-agent-sdk-migration-playbook-from-claude-code-sdk-2026 , and our production-patterns guide /blog/claude-agent-sdk-production-patterns-guide covers context management on that side. 07 — BedrockAnthropicBedrock stops guessing your region. On 0.x, constructing AnthropicBedrock or AsyncAnthropicBedrock with no region configured silently fell back to us-east-1 . On 1.x, MIGRATION.md documents that the same construction raises a ValueError instead. The resolution order is explicit: an aws region= constructor argument first, then the AWS REGION or AWS DEFAULT REGION environment variables, then the boto3 profile configuration. If none of those yields a region, the client refuses to start. The SDK docs frame this class carefully: AnthropicBedrock is retained for existing applications on the Bedrock InvokeModel path, while AnthropicBedrockMantle is the recommended class for new Bedrock projects. The region change is about the legacy class, which is precisely the one most likely to be sitting in an older service with a minimal constructor call. Pass aws region explicitly AnthropicBedrock aws region="eu-central-1" . Highest precedence, visible in code review, and a harmless no-op on 0.x — so it is safe to land before the SDK upgrade. AWS REGION or AWS DEFAULT REGION Second in the resolution order. Right when the same image runs in several regions and the deployment layer already owns the variable. Verify it reaches the process, not just the shell. Lean on the shared AWS config Lowest precedence. Works on developer machines with a configured profile and fails on a clean CI runner — which is the environment where the new ValueError will find you first. Check who reads raw events Unknown Bedrock stream events are now skipped rather than yielded; MIGRATION.md calls out amazon-bedrock-invocationMetrics specifically. Any dashboard fed from that event needs a new source. The design call is the right one. A client that quietly routes production traffic to a region nobody chose is a data-residency incident waiting for an auditor, and the old default made that the path of least resistance. The cost is a one-time startup failure in any environment that relied on it — which is why the explicit constructor argument is worth landing this week even if the SDK upgrade itself waits. 08 — Smaller BreaksAsync raw responses, headers, and the structured-output rename. The remaining changes are mechanical, but two of them hide in code that runs rarely. On the async client, .with raw response results now require await response.parse where 0.x allowed a synchronous .parse . The .text and .content properties on raw responses became methods — response.text and response.read — and the response gains directly accessible json , iter bytes , iter text and iter lines . Before 0.x : async raw response response = await client.messages.with raw response.create params message = response.parse request id = response.headers.get "request-id" body = response.text After 1.x response = await client.messages.with raw response.create params message = await response.parse request id = response.headers.get "Request-Id" names are case-insensitive now body = response.text Headers are the second quiet one. Names are now case-insensitive, which is a loosening, but raw bytes values now raise and must be decoded to str first — a tightening that lands on whichever middleware stuffs a signed token into a header without decoding it. Structured output is the third: passing a raw schema dict as output format= is removed from message methods in favour of output config={"format": {...}} , and the parse , stream and count tokens helpers accept only types for output format= . Finally, messages.parse stream=True is gone, which MIGRATION.md notes “never worked” — use messages.stream with output format= and read stream.get final message .parsed output . None of these justify delaying the migration on their own. They do justify running the migration on a branch with the full test suite, rather than bumping the version in a dependency-update bot and merging on green, because raw-response code and header middleware are exactly the paths most suites do not exercise. 09 — Hold-Back PinPin to 0.125.0 or migrate: a decision , not a default. The hold-back pin is a real, currently installable version, not a guess: anthropic==0.125.0 , the last 0.x release, published on August 19 and still on PyPI. The looser form anthropic =0.125,<1 does the same job while leaving room for any further 0.x uploads. Either way, a pin is a dated exception with an owner, and the table below is the decision behind it: the symptom that forces the pin, the pin itself, how much pressure sits behind the deadline, and what changes when you do migrate. | Symptom | Recommended pin | Deadline pressure | What changes when you migrate | |---|---|---|---| | Service is still on Python 3.9 | anthropic==0.125.0 | High — the 0.x line is the only SDK path for 3.9, and it receives no 1.x features or fixes | Runtime moves to 3.10+ first; the SDK upgrade follows in the same change window | | Still calling client.completions.create | anthropic =0.125,<1 | Highest — this surface was long-deprecated before v1.0 removed the client | Port to messages.create ; prompt strings built from HUMAN PROMPT / AI PROMPT become message arrays | | Agent loop depends on client-side compaction control | anthropic =0.125,<1 | Medium — nothing breaks on 0.x, but the capability now lives server-side behind a beta | betas= "compact-2026-01-12" plus context management with a trigger of 50,000 input tokens or more | | Relying on AnthropicBedrock’s old us-east-1 default | No pin needed | Low — set the region explicitly today; it is a no-op on 0.x and required on 1.x | Construction raises ValueError until aws region, AWS REGION / AWS DEFAULT REGION, or a boto3 profile supplies a region | | Sending non-default temperature / top p / top k | No pin helps | Already failing on the seven current models; model-level, not SDK-level | Delete or default the values for current models; move older-model calls to extra body with a comment naming the dependency | The last row is the one to internalise. Pinning protects you from SDK-level changes; it does nothing for a behaviour the model enforces. That is the general lesson of a 1.0 like this one, and it maps onto the framework in our API versioning decision matrix /blog/api-versioning-strategies-2026-engineering-decision-matrix : a client library’s major version is a contract about the typed surface, and the typed surface can be narrower than the wire protocol or wider than what a given model honours. When the three disagree, the model wins, and your tests should be written against the model. Looking forward, the direction of travel is not hard to read. Anthropic’s typed surface and the sampling restriction on its current models now agree, the Agent SDK and Codex CLI have both been through their own config migrations this summer — Codex’s was a config-schema move /blog/codex-cli-rust-migration-playbook-config-changes-2026 rather than a transport swap — and the pattern across vendors is that SDK majors are increasingly the place where deprecations get enforced rather than announced. The teams that cope best keep a single adapter module around each vendor client, so the next major touches one file. If you are building or operating agentic systems on Claude and want that adapter layer designed before the next migration rather than during it, our AI transformation engagements /services/ai-transformation start with exactly that audit, and our web development team /services/web-development handles the runtime and dependency upgrades that usually come bundled with it. 10 — ConclusionMigrate the behaviour changes deliberately ; the rest is find-and-replace. The SDK’s typed surface and the models’ sampling rules now agree — the real work is in the behaviour changes, not the renames. Anthropic Python SDK v1.0 is a deprecation gate. The HTTP layer moves to httpx2, “a maintained, API-compatible fork” in Anthropic’s own careful wording; the floor rises to Python 3.10; Text Completions, the sampling parameters and client-side compaction leave the typed surface; AnthropicBedrock refuses to guess a region. Fifteen documented changes, and only one is enforced by the models themselves — sampling, where seven current models already return a 400 on any non-default value regardless of how the request arrives. The migration itself is an afternoon for a service that is on Python 3.10+, on Messages, and not building its own httpx objects. It is a planned change for anyone running a long agent loop on client-side compaction, instrumenting httpx by module name, or constructing AnthropicBedrock without a region. The first two break with nothing raised at all; the third refuses to construct the client, which is loud but lands at startup in whichever environment relied on the old default. Land the region argument and the alias httpx call first; both are safe on 0.x. If you cannot move this week, anthropic==0.125.0 is a real pin with a real date, and it buys you time on everything except sampling. Give it an owner, and write the tests that matter against the model rather than the SDK — because that is the boundary this release just made visible.