API Gateway
Create APIs, their configs from OpenAPI or gRPC documents, and the gateways that use them.
24Supported6Not testedof 30 methods
Control plane only: gateways don't serve traffic.
Connect
Section titled “Connect”Requests go to $VERA_ENDPOINT/_gcp/apigateway/v1/. As in Google Cloud, APIs and API configs live in global and gateways in a region, such as us-central1. For gcloud, add this override to the shared setup:
export CLOUDSDK_API_ENDPOINT_OVERRIDES_APIGATEWAY="$VERA_ENDPOINT/_gcp/apigateway/"Example
Section titled “Example”Create an API, give it a config from an OpenAPI document and attach the config to a gateway. Save this as openapi.yaml:
swagger: "2.0"info: { title: example-api, version: "1.0.0" }schemes: [https]produces: [application/json]paths: /hello: get: operationId: hello x-google-backend: { address: "https://example.com/hello" } responses: { "200": { description: OK } }gcloud api-gateway apis create example-apigcloud api-gateway api-configs create example-config \ --api=example-api --openapi-spec=openapi.yamlgcloud api-gateway gateways create example-gateway \ --api=example-api --api-config=example-config --location=us-central1gcloud api-gateway gateways describe example-gateway \ --location=us-central1 --format=jsonEach create waits for its operation, which the emulator finishes at once. The last command prints the gateway. Its defaultHostname and timestamps differ on every run.
{ "apiConfig": "projects/example-project/locations/global/apis/example-api/configs/example-config", "createTime": "2026-11-02T20:16:38.232128Z", "defaultHostname": "example-gateway-5s5xkgid.uc.gateway.dev", "displayName": "example-gateway", "effectiveStreamingMode": "EFFECTIVE_STREAMING_MODE_DISABLED", "name": "projects/example-project/locations/us-central1/gateways/example-gateway", "state": "ACTIVE", "updateTime": "2026-11-02T20:16:38.232128Z"}A config’s OpenAPI document is sent base64-encoded. Each create returns a long-running operation that is already done.
BASE="$VERA_ENDPOINT/_gcp/apigateway/v1/projects/example-project/locations"SPEC=$(base64 < openapi.yaml | tr -d '\n')
curl -X POST "$BASE/global/apis?apiId=example-api" \ -H "Content-Type: application/json" -d '{}'
curl -X POST "$BASE/global/apis/example-api/configs?apiConfigId=example-config" \ -H "Content-Type: application/json" \ -d '{"openapiDocuments":[{"document":{"path":"openapi.yaml","contents":"'"$SPEC"'"}}]}'
curl -X POST "$BASE/us-central1/gateways?gatewayId=example-gateway" \ -H "Content-Type: application/json" \ -d '{"apiConfig":"projects/example-project/locations/global/apis/example-api/configs/example-config"}'
curl "$BASE/us-central1/gateways/example-gateway"The last request returns the gateway. Its defaultHostname and timestamps differ on every run.
{ "apiConfig": "projects/example-project/locations/global/apis/example-api/configs/example-config", "createTime": "2026-11-02T18:44:46.120171Z", "defaultHostname": "example-gateway-5s5xkgid.uc.gateway.dev", "displayName": "example-gateway", "effectiveStreamingMode": "EFFECTIVE_STREAMING_MODE_DISABLED", "name": "projects/example-project/locations/us-central1/gateways/example-gateway", "state": "ACTIVE", "updateTime": "2026-11-02T18:44:46.120171Z"}Supported features
Section titled “Supported features”- APIs in
global: create, read, list, update and delete. - API configs from OpenAPI 2.0 or 3 documents, or gRPC descriptors with a service config, parsed and checked for common mistakes.
- Gateways in supported regions, each with a generated
defaultHostname, switching between configs. - Service accounts: a named account must exist and be enabled in the IAM emulator. Without one, the project’s default Compute Engine account is used.
- IAM policies on APIs, configs and gateways, with etag checks and validation.
- Long-running operations for every change, already done when returned.
v1betaandv1alpha1requests, including those from Terraform’sgoogle-betaprovider.
Limitations
Section titled “Limitations”- No traffic. A gateway’s
defaultHostnamedoesn’t resolve: nothing routes requests, checks API keys or JWTs, or calls yourx-google-backend. - Partial validation. Documents are checked for common mistakes, not against the full OpenAPI specification. External
$refs aren’t resolved, and gRPC descriptors are decoded, not compiled. - IAM isn’t enforced. Policies are stored and validated, but requests aren’t authorized against them.
- Service accounts aren’t fully authorized. Missing or disabled accounts and Google service agents are refused, but there’s no complete
actAspermission check. - Operations finish immediately, with no provisioning delay.
- Alpha-only fields (
apiController,serviceRollout,uniqueIdand a config’sgatewayConfig) answer501 Not Implementedonv1alpha1, as does patching a config’sgatewayConfigonv1beta.
API coverage
Section titled “API coverage”Measured 2 November 2026 against recorded Google Cloud responses. What the statuses mean
apis
8 methods · 1 not tested
| Method | Status | Notes |
|---|---|---|
| create | Supported | Create in global only. |
| get | Supported | |
| list | Supported | |
| patch | Supported | Only labels and displayName can change. |
| delete | Supported | Refused while the API has configs. |
| getIamPolicy | Supported | |
| setIamPolicy | Supported | |
| testIamPermissions | Not tested | Answers for a caller that owns the project. |
configs
8 methods · 1 not tested
| Method | Status | Notes |
|---|---|---|
| create | Supported | OpenAPI 2.0 or 3, or gRPC. Documents are partly validated. |
| get | Supported | view=FULL returns the source documents. |
| list | Supported | |
| patch | Supported | Only labels and displayName can change. |
| delete | Supported | Refused while a gateway uses the config. |
| getIamPolicy | Supported | |
| setIamPolicy | Supported | |
| testIamPermissions | Not tested | Answers for a caller that owns the project. |
gateways
8 methods · 1 not tested
| Method | Status | Notes |
|---|---|---|
| create | Supported | defaultHostname is generated. Nothing is served there. |
| get | Supported | |
| list | Supported | |
| patch | Supported | |
| delete | Supported | |
| getIamPolicy | Supported | |
| setIamPolicy | Supported | |
| testIamPermissions | Not tested | Answers for a caller that owns the project. |
operations
4 methods · 1 not tested
| Method | Status | Notes |
|---|---|---|
| get | Supported | Operations finish immediately. |
| list | Not tested | |
| cancel | Supported | A finished operation is left unchanged. |
| delete | Supported |
locations
2 methods · 2 not tested
| Method | Status | Notes |
|---|---|---|
| get | Not tested | |
| list | Not tested | 44 locations, including global. |