Running Claude on Google Cloud Vertex AI: Quotas and Service Accounts
Google Cloud Vertex AI puts Claude behind your existing GCP project: a service account authenticates the calls, project quota bounds how much traffic you can send, and a regional endpoint decides where inference actually runs.
Summary
Vertex AI authenticates differently from both the direct Anthropic API and Amazon Bedrock - there is no API key at all, only Google's Application Default Credentials resolved through a service account.
Three things need to exist before a call succeeds: a service account with the right IAM role, the Vertex AI API enabled with sufficient quota on the project, and a deliberate choice of region rather than an assumed default.
Missing any of those three produces a permission or quota error that looks like an SDK bug but is really a provisioning gap, the same failure shape as an unprovisioned Bedrock account.
This page covers service account setup, requesting and monitoring quota, and choosing between a specific region and Vertex AI's global routing, then shows the request shape application code actually uses.
Recipe
Quick-reference recipe card - copy-paste ready.
from anthropic import AnthropicVertex
client = AnthropicVertex(project_id="my-gcp-project", region="us-east5")
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Summarize this ticket in one sentence."}],
)
print(response.content[0].text)When to reach for this:
- Your organization already runs production workloads on Google Cloud and wants Claude usage to flow through existing IAM and billing.
- You need Claude's traffic to stay inside a GCP-managed network and compliance boundary.
- You want Claude spend to count against an existing Google Cloud committed-use discount.
- You are integrating Claude into a service that already authenticates other GCP APIs via a service account.
Working Example
import os
from anthropic import AnthropicVertex
import anthropic
# project_id and region are both required - there is no default project or region.
client = AnthropicVertex(
project_id=os.environ["GCP_PROJECT_ID"],
region=os.environ.get("GCP_REGION", "us-east5"),
)
def summarize_ticket(ticket_text: str) -> str:
"""Call Claude on Vertex AI and return a one-sentence summary.
Assumes Application Default Credentials resolve to a service account
with the Vertex AI User role, and that the project has quota for
claude-sonnet-5 in the target region.
"""
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
messages=[
{
"role": "user",
"content": f"Summarize this support ticket in one sentence:\n\n{ticket_text}",
}
],
)
return response.content[0].text
except anthropic.PermissionDeniedError:
raise RuntimeError(
"Service account lacks the Vertex AI User role, or the Vertex AI "
"API is not enabled on this project."
)
except anthropic.RateLimitError:
raise RuntimeError(
"Project quota exceeded for this model and region - request a "
"quota increase in the Google Cloud console."
)
if __name__ == "__main__":
ticket = "Customer reports login page returns a 500 error after the latest deploy."
print(summarize_ticket(ticket))What this demonstrates:
AnthropicVertextakesproject_idandregionas required constructor arguments - neither has a default, unlike the direct API's zero-argument client.- Authentication is entirely Application Default Credentials - there is no Anthropic API key anywhere in this code.
- Catching
PermissionDeniedErrorandRateLimitErrorseparately turns the two most common first-deploy failures (missing IAM role, exhausted quota) into an actionable message.
Deep Dive
How It Works
- Every Vertex AI request authenticates as a service account via Google's Application Default Credentials chain - locally this resolves through
gcloud auth application-default login, and in production it resolves through whatever service account is attached to the compute environment (a GCE instance, a Cloud Run service, or a GKE workload identity binding). - The service account needs the Vertex AI User IAM role (or an equivalent custom role with the matching permissions) bound at the project or resource level before any call succeeds.
- Enabling the Vertex AI API on the project is a separate step from IAM binding - a service account with the right role still fails if the API itself was never enabled for that project.
- Quota is tracked per project, per model, and per region - a project with generous quota in
us-east5may have none ineurope-west1until a separate increase is requested there. - Region selection determines where inference actually executes: a specific region pins processing to that location, a multi-region value spans a geography, and
"global"lets Anthropic route to whichever region has capacity.
Service Account Setup
# Create a service account dedicated to Claude API calls.
gcloud iam service-accounts create claude-api-caller \
--display-name="Claude API caller"
# Grant the Vertex AI User role, scoped to the project.
gcloud projects add-iam-policy-binding my-gcp-project \
--member="serviceAccount:claude-api-caller@my-gcp-project.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
# Enable the Vertex AI API if it isn't already.
gcloud services enable aiplatform.googleapis.com --project=my-gcp-project- Creating a dedicated service account for Claude traffic, rather than reusing a broad general-purpose account, keeps IAM auditing straightforward and limits blast radius if credentials are ever compromised.
roles/aiplatform.useris the standard predefined role for invoking Vertex AI models; a narrower custom role is worth building once your permission needs are well understood.- Enabling the API is idempotent - running it again on an already-enabled project is a no-op, so it's safe to include in setup scripts.
Region and Endpoint Choices
| Region value | Behavior | Best fit |
|---|---|---|
Specific region (e.g. us-east5) | Inference pinned to that exact location. | Data residency or latency requirements that mandate a fixed location. |
Multi-region (e.g. us, eu) | Routes within a geography, not a single data center. | Latency-sensitive workloads with a broad but bounded residency requirement. |
"global" | Anthropic routes to the best available region. | Default choice when there is no residency constraint - maximizes availability during regional capacity limits. |
- Quota increases are region-scoped, so switching a workload from a specific region to
"global"(or vice versa) later may require a fresh quota conversation, not just a code change. - A regulated workload that must keep processing inside a named jurisdiction should pin a specific region rather than use
"global", even though"global"is the more resilient default for everything else.
Python Notes
from anthropic import AnthropicVertex
# Streaming works identically to the direct API - only the client class differs.
client = AnthropicVertex(project_id="my-gcp-project", region="us-east5")
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Draft a short release note."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)AnthropicVertexexposes the samemessages.createandmessages.streammethods as the direct-API and Bedrock clients - code written against the direct API needs only a client-construction change to run on Vertex AI.- Installing the SDK with the
vertexextra (pip install "anthropic[vertex]") pulls in the Google auth libraries the client needs; the plainanthropicpackage alone is not enough.
Parameters & Return Values
| Parameter | Type | Description |
|---|---|---|
project_id | str | Required constructor argument. The GCP project that owns quota and billing for these calls. |
region | str | Required constructor argument. A specific region, a multi-region value, or "global". |
model | str | Current-generation Claude model IDs on Vertex AI are unprefixed, matching the direct API's bare model string. |
Gotchas
- Assuming the direct API's zero-argument client pattern works here.
AnthropicVertex()with no arguments raises immediately - bothproject_idandregionare required. Fix: always pass both explicitly, typically sourced from environment configuration. - Service account has the IAM role but the Vertex AI API was never enabled. The role binding succeeds silently, but calls still fail. Fix: confirm
aiplatform.googleapis.comis enabled on the project, not just that the IAM role exists. - Requesting quota in the wrong region. Quota is granted per region, so a quota increase approved for
us-east5does nothing for a client configured withregion="europe-west1". Fix: match the quota request region to the client's configured region exactly. - Treating
"global"as always the safest choice. For a regulated workload with a data residency requirement,"global"can route inference to a region outside the required jurisdiction. Fix: pin a specific region whenever residency is a hard requirement, and use"global"only when there is no such constraint. - Forgetting the
vertexextra when installing the SDK. A plainpip install anthropicdoes not include the Google auth dependenciesAnthropicVertexneeds. Fix: install withpip install "anthropic[vertex]". - Reusing a broad, pre-existing service account instead of a scoped one. This makes IAM auditing for Claude-specific traffic much harder later. Fix: create a dedicated service account for Claude API calls with only the roles it needs.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Direct Anthropic API | You want the fastest path to new models and features, with no GCP dependency. | Your organization requires traffic to stay inside GCP-managed IAM and network boundaries. |
| Amazon Bedrock | Your organization is standardized on AWS instead of GCP. | You have no AWS footprint and would be onboarding a new cloud vendor for this alone. |
| A self-hosted gateway in front of Vertex AI | You want to add caching, centralized rate limiting, or fallback to another provider without touching application code. | You have a single simple workload where the added infrastructure isn't worth the operational cost. |
FAQs
Do I need an Anthropic API key to use Claude on Vertex AI?
No. Authentication is entirely through Google's Application Default Credentials, resolved to a service account - there is no separate Anthropic-issued API key involved.
Why does `AnthropicVertex()` raise an error with no arguments?
Both project_id and region are required constructor arguments with no defaults, unlike the direct API's client which can be constructed with zero arguments by reading an environment variable.
What IAM role does the service account need?
- The
roles/aiplatform.userpredefined role, or an equivalent custom role with matching permissions - The Vertex AI API itself enabled on the project, which is a separate step from the IAM binding
How is quota scoped on Vertex AI?
Per project, per model, and per region. A quota increase approved for one region does not apply to a different region configured on the client.
What's the difference between a specific region, a multi-region value, and "global"?
A specific region pins inference to one location; a multi-region value routes within a geography; "global" lets Anthropic route to whichever region has capacity, which is the most resilient default absent a residency requirement.
Should a regulated workload use `region="global"`?
Usually not. A hard data residency requirement calls for pinning a specific region, since "global" can route inference outside a required jurisdiction.
Can the same application code run against both the direct API and Vertex AI?
Mostly, yes. Both clients expose the same messages.create and messages.stream methods - the differences are client construction (API key vs. project and region) and, for older dated-snapshot models, the model ID format.
Do current Claude model IDs need a prefix on Vertex AI?
No, for current-generation models the ID matches the direct API's bare model string. Dated-snapshot models use an @ version separator instead of a prefix.
What package extra do I need to install for Vertex AI support?
pip install "anthropic[vertex]" - the plain anthropic package does not include the Google auth dependencies AnthropicVertex requires.
Does streaming work the same way on Vertex AI as on the direct API?
Yes. client.messages.stream(...) behaves identically, including the text_stream convenience iterator.
Is enabling the Vertex AI API the same as granting IAM access?
No, they're separate steps. A service account can have the right IAM role while the API itself is still disabled on the project, and either gap alone causes calls to fail.
Why might a team choose Vertex AI over the direct API even though it's more setup?
To keep Claude traffic inside existing GCP IAM and network governance, and to have the spend count against an existing Google Cloud billing or discount agreement rather than a new vendor relationship.
Related
- Choosing Between Direct API, Bedrock, and Vertex AI for Claude - decide whether Vertex AI is the right platform before provisioning it.
- Enterprise Deployment Basics - the minimal first call across all three platforms, including Vertex AI.
- Deploying Claude on Amazon Bedrock: IAM, Provisioning, and Cross-Region Inference - the equivalent provisioning steps on AWS.
- Data Residency and Region-Pinning Checklist for Regulated Workloads - how region choice on Vertex AI interacts with compliance requirements.
- Comparing Bedrock, Vertex AI, and Direct Anthropic API Access - trade-offs across all three platforms in one table.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, pricing, and SDK versions move quickly - verify current specifics at platform.claude.com/docs before relying on them.