API key + project/location with Vertex AI Express Mode — bug or missing feature?
Context
I'm not sure if this is a bug or a feature that hasn't been implemented yet, but I wanted to flag it either way.
With Vertex AI Express Mode, it's now possible to authenticate to project-scoped Vertex AI endpoints using just an API key — no OAuth, ADC, or service account required. This works at the API level today. However, the SDK doesn't allow this combination.
The problem
Passing both apiKey and project/location to the Client constructor throws an ArgumentException:
// Throws: "Project/location and API key are mutually exclusive in the client initializer."
var client = new Client(
vertexAI: true,
apiKey: "my-api-key",
project: "my-project",
location: "us-central1");
This prevents SDK users from accessing project-scoped endpoints (e.g. Veo video generation, Imagen) with API key auth through the SDK.
What works at the API level
The following request pattern works when sent directly via HttpClient:
POST https://us-central1-aiplatform.googleapis.com/v1beta1/projects/my-project/locations/us-central1/publishers/google/models/veo-3.1-generate-001:predictLongRunning
x-goog-api-key: <api-key>
No Authorization: Bearer header needed. The API key alone is sufficient, and the project/location in the URL path scopes the request correctly. I've confirmed this works end-to-end for Veo video generation.
Why this is a problem in practice
Some Vertex AI features (Veo video generation, potentially others) require the project path in the URL. Users who authenticate via API key (e.g. Vertex AI Express Mode, environments without gcloud/ADC) currently cannot use these features through the SDK at all.
The only way to make this work today is to bypass SDK internals, which is fragile and not suitable for production use.
What I'd expect to work
When vertexAI: true and an apiKey is provided alongside project/location, the SDK would:
- Accept the combination without throwing
- Build URLs with the
projects/{project}/locations/{location}/ prefix (as it does for credential-based Vertex AI auth)
- Authenticate using
x-goog-api-key only (no Bearer token)
Additional notes
- Google.GenAI SDK version: 1.6.1
- The Python SDK (
googleapis/python-genai) has the same restriction in BaseApiClient.__init__
- Affects any project-scoped Vertex AI endpoint used with API key auth
- If this is intentionally blocked, it would be helpful to understand why — since the API itself accepts it
API key + project/location with Vertex AI Express Mode — bug or missing feature?
Context
I'm not sure if this is a bug or a feature that hasn't been implemented yet, but I wanted to flag it either way.
With Vertex AI Express Mode, it's now possible to authenticate to project-scoped Vertex AI endpoints using just an API key — no OAuth, ADC, or service account required. This works at the API level today. However, the SDK doesn't allow this combination.
The problem
Passing both
apiKeyandproject/locationto theClientconstructor throws anArgumentException:This prevents SDK users from accessing project-scoped endpoints (e.g. Veo video generation, Imagen) with API key auth through the SDK.
What works at the API level
The following request pattern works when sent directly via
HttpClient:No
Authorization: Bearerheader needed. The API key alone is sufficient, and the project/location in the URL path scopes the request correctly. I've confirmed this works end-to-end for Veo video generation.Why this is a problem in practice
Some Vertex AI features (Veo video generation, potentially others) require the project path in the URL. Users who authenticate via API key (e.g. Vertex AI Express Mode, environments without gcloud/ADC) currently cannot use these features through the SDK at all.
The only way to make this work today is to bypass SDK internals, which is fragile and not suitable for production use.
What I'd expect to work
When
vertexAI: trueand anapiKeyis provided alongsideproject/location, the SDK would:projects/{project}/locations/{location}/prefix (as it does for credential-based Vertex AI auth)x-goog-api-keyonly (no Bearer token)Additional notes
googleapis/python-genai) has the same restriction inBaseApiClient.__init__