Teams that run Claude on more than one platform — for failover, procurement reasons, or a migration in flight — tend to sprout if platform == "bedrock" branches all over the codebase. The fix is old-fashioned software engineering: a factory. Because Anthropic, AnthropicAWS, AnthropicBedrockMantle, AnthropicVertex, and AnthropicFoundry all expose the same client.messages.create(...) surface, one function can decide which to construct, and everything downstream calls the result identically.
The factory
import os
from anthropic import (Anthropic, AnthropicAWS, AnthropicBedrockMantle,
AnthropicVertex, AnthropicFoundry)
def make_client():
platform = os.environ.get("CLAUDE_PLATFORM", "1p")
if platform == "aws": # Claude Platform on AWS
return AnthropicAWS() # reads AWS_REGION + ANTHROPIC_AWS_WORKSPACE_ID
if platform == "bedrock":
return AnthropicBedrockMantle(aws_region=os.environ["AWS_REGION"])
if platform == "vertex":
return AnthropicVertex(project_id=os.environ["GCP_PROJECT_ID"],
region=os.environ.get("VERTEX_REGION", "global"))
if platform == "foundry":
return AnthropicFoundry() # reads ANTHROPIC_FOUNDRY_API_KEY / _RESOURCE
return Anthropic() # 1P; reads ANTHROPIC_API_KEY
Each branch leans on the client's own configuration behavior rather than duplicating it. AnthropicAWS() resolves region and workspace from AWS_REGION and ANTHROPIC_AWS_WORKSPACE_ID and raises at construction if either is missing — a deliberately loud failure, before any request is sent. AnthropicFoundry() auto-reads ANTHROPIC_FOUNDRY_API_KEY, ANTHROPIC_FOUNDRY_RESOURCE, and ANTHROPIC_FOUNDRY_BASE_URL. The Bedrock and AWS clients pull credentials from the standard AWS chain; Vertex uses Application Default Credentials. The full variable set is in the environment-variable matrix.
Note the installation extras: the Bedrock client ships with pip install -U "anthropic[bedrock]" and the Vertex client with pip install -U "anthropic[vertex]". Install what your deployment targets need.
The factory alone is not enough: model IDs
The one input that must still vary by platform is the model identifier. Bedrock prefixes IDs with anthropic. (anthropic.claude-opus-4-8); older models on Google Cloud carry an @date suffix (claude-haiku-4-5@20251001); everywhere else uses bare IDs (claude-opus-4-8); and on Foundry the value is technically the deployment name, which defaults to the model ID. So a portable call site needs a second small function — a model resolver — alongside the factory:
MODEL_FORMS = {
"claude-opus-4-8": {"bedrock": "anthropic.claude-opus-4-8"},
"claude-haiku-4-5": {"bedrock": "anthropic.claude-haiku-4-5-20251001-v1:0",
"vertex": "claude-haiku-4-5@20251001"},
}
def resolve_model(canonical: str, platform: str) -> str:
return MODEL_FORMS.get(canonical, {}).get(platform, canonical)
Default to the canonical bare ID and override only where a platform documents a different form. The two prefix/suffix rules are covered in depth in the Bedrock prefix rule and the Vertex @date lookup.
What not to hide in the factory
A factory should make the platforms interchangeable where they genuinely are — and it is tempting to pretend they are interchangeable everywhere. They are not:
- Feature availability differs. Anthropic's Message Batches API and Files API exist on the Claude API and Claude Platform on AWS but not on Bedrock or Vertex; on Foundry the Files API is beta and Batches is unavailable. Gate these with a capability map (see gating beta features by platform), not with try/except.
- Error surfaces differ. SDK typed exceptions are consistent, but rate-limit behavior and headers vary — Foundry, for instance, does not return Anthropic's
anthropic-ratelimit-*headers. - Pricing semantics differ. Notably, Vertex charges long-context rates for requests at or above 200K tokens, while Anthropic bills the full 1M window at standard per-token rates — a cost model your router may care about.
Where to go next
Wire the factory's inputs with a twelve-factor env layout, and see migrating between clouds for how this pattern pays off when you actually switch. The quickstart has single-platform starter code.