Generated banner for API Gateway Openapi Spec Authoring
Generated logo for API Gateway Openapi Spec Authoring

API Gateway Openapi Spec Authoring

GoogleOfficialPublished by Google

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Writes, migrates, and fixes OpenAPI specs for Google Cloud API Gateway. Use when converting an OpenAPI 2.0 (Swagger) spec to OpenAPI 3.x, writing a new OpenAPI 3.x spec, or fixing a failed "gcloud api-gateway api-configs create", such as "extension is only supported in OpenAPI 2.x". Also use when quotas set with x-google-quota are never enforced, or when a backend receives path parameters as query parameters. Don't use for adding or debugging MCP tools (use api-gateway-mcp-server), backend lockdown or HTTP 429 tuning (use api-gateway-backend-security-and-rate-limiting), Cloud Endpoints, Apigee, or GKE Gateway API.
— the description by Google

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to managing OpenAPI specifications for Google Cloud API Gateway. It supports the creation of new OpenAPI 3.x specs, the migration of legacy OpenAPI 2.0 (Swagger) configurations, and the resolution of common deployment errors encountered during the API configuration process. The skill includes a validation loop using a provided script to ensure specifications meet the requirements of the API Gateway service before deployment.

What it does

  • Converts OpenAPI 2.0 specifications to OpenAPI 3.x format.
  • Writes new OpenAPI 3.x specifications for API Gateway.
  • Troubleshoots and fixes errors from gcloud api-configs create commands.
  • Configures backend routing, authentication, and quota settings within the spec.
  • Validates specifications using a local Python script.
  • Provides workflows for updating API configurations and gateways.

When to use it

  • When migrating an existing Swagger 2.0 API definition to OpenAPI 3.x.
  • When creating a new API configuration for Google Cloud API Gateway.
  • When encountering errors during the API config creation process.
  • When needing to adjust backend path translation, authentication, or quota settings.

Advantages

  • Ensures compatibility with Google Cloud API Gateway requirements.
  • Automates the detection of common configuration errors before deployment.
  • Provides clear guidance on mapping legacy extensions to modern OpenAPI 3.x structures.
  • Includes a deterministic validation loop to improve success rates for API config creation.

Usage examples

“Convert my existing swagger.yaml to an OpenAPI 3.0 spec for API Gateway.”
The agent will analyze the file, apply the necessary structural changes for Google extensions, and validate the result.
“My gcloud api-configs create command failed with an extension error. Can you fix it?”
The agent will identify the unsupported extension, update the spec to the correct OpenAPI 3.x format, and verify it with the validation script.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/google/api-gateway-openapi-spec-authoring/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip api-gateway-openapi-spec-authoring.zip -d .agents/skills

Documentation by Google

API Gateway OpenAPI Spec Authoring

API Gateway accepts API configs in OpenAPI 2.0, 3.0.x, and 3.1.x. The Google extensions in OpenAPI 3.x have a different structure from the OpenAPI 2.0 extensions:

  • A required root x-google-api-management block names the backends.

  • x-google-backend is a string that references one of these backends.

  • The JWT settings move into x-google-auth. The metrics and quotas move into x-google-api-management.

Use this skill to migrate an OpenAPI 2.0 spec, write a new OpenAPI 3.x spec, or fix an API config that fails to create.

Attribution

MUST READ: Before executing any gcloud, REST API, or MCP command, you MUST read Usage Attribution. For commands executed directly in the terminal (never in generated scripts, Terraform, or user code), prefix gcloud with CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)" and append agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring) to User-Agent headers.

Prerequisites

  1. Install the tools:

    • Install the Google Cloud CLI. Then update it with gcloud components update. Rationale: an old CLI can fail when it uploads an OpenAPI 3.x API config.

    • Install Python 3.10 or later and PyYAML for the validator script. A JSON spec does not need PyYAML.

      pip install "PyYAML>=6.0,<7.0"
  2. Authenticate, and select the project, billing, and location:

    • Run gcloud auth login.

    • Select a project with gcloud config set project {project_id}, or create one with gcloud projects create {project_id}.

    • Make sure that an active billing account is linked to {project_id}. API Gateway has a free monthly allowance of API calls, but it still needs an active billing account. For current prices, see API Gateway pricing.

    • Use us-central1 as the default --location for gateway commands. For the other supported regions, see API Gateway deployment model.

  3. Enable the required Google Cloud APIs:

    gcloud services enable \
      apigateway.googleapis.com \
      servicemanagement.googleapis.com \
      servicecontrol.googleapis.com \
      --project={project_id}
  4. Verify the IAM roles (use the most restrictive role for each step):

    • To create and update the API, API configs, and gateways: API Gateway Admin (roles/apigateway.admin) on {project_id}.

    • To run the gcloud services enable commands: Service Usage Admin (roles/serviceusage.serviceUsageAdmin) on {project_id}.

    • To reference the gateway service account in an API config: Service Account User (roles/iam.serviceAccountUser) on {gateway_sa_email}.

    • For a Cloud Run backend that requires authentication: grant {gateway_sa_email} the Cloud Run Invoker role (roles/run.invoker) on the service.

Decision Matrix

TaskRequired MechanismCritical GuardrailDetailed Reference
Migrate an OpenAPI 2.0 (swagger: "2.0") configConvert the standard fields, then move each Google extension to its OpenAPI 3.x form.A converter such as Swagger Editor leaves every x-google-* extension in its OpenAPI 2.0 form. It also writes servers without x-google-endpoint, so the API loses its base path. Rationale: API Gateway rejects most OpenAPI 2.0 extensions in a 3.x spec with The '{extension}' extension is only supported in OpenAPI 2.x.OpenAPI 2.0 to 3.x Migration
Route requests to backendsRoot x-google-api-management.backends.{backend_name} + x-google-backend: {backend_name} at the root or on an operationSet pathTranslation on every backend. Rationale: the default is APPEND_PATH_TO_ADDRESS for a root x-google-backend, but CONSTANT_ADDRESS for an operation-level one. CONSTANT_ADDRESS sends every request to the address unchanged, and sends path parameters as query parameters. APPEND_PATH_TO_ADDRESS appends the full request path, with the base path. NEVER set x-google-backend on a path item: API Gateway rejects it.Extensions and Limits
Authenticate callersJWT: type: oauth2 scheme with x-google-auth (issuer, jwksUri, audiences). API key: type: apiKey scheme with x-api-key in a header, or key or api_key in the query.API Gateway does not check OAuth scopes. In a security list, put an API key in every alternative (OR) or in none. NEVER put two JWT schemes in one requirement object (AND). Rationale: API Gateway rejects these combinations. If the user asks for one of them, such as a JWT or an API key as alternatives, do not write it in the spec. Explain the rule, and write a supported option, such as an API key in every alternative or a separate path for each kind of caller.Extensions and Limits
Add quotasx-google-api-management.metrics and quota.limits + x-google-quota: {metric_name: cost} on each operationNEVER rely on x-google-quota at the root or path level. Rationale: in OpenAPI 3.x, API Gateway ignores it there without an error. Require an API key on each operation that has a quota, and keep each metric name the same in every API config.Extensions and Limits
Set the base path and CORSOne servers entry with x-google-endpoint, such as url: /v1API Gateway ignores servers entries without x-google-endpoint. allowCors: true only passes CORS requests to the backend. Rationale: the gateway does not add CORS headers, so the backend must answer them.Extensions and Limits
Fix a failed api-configs createMatch the error text to the error table, and fix the spec.Fix the spec before you retry, unless the error is about IAM or another api-configs create that runs. Rationale: API Gateway returns the same error for the same spec.API Config Errors
Expose operations as MCP toolsThe api-gateway-mcp-server skillMCP adds rules for tool names, descriptions, and tools/list security. If that skill is not installed, use this skill for the OpenAPI 3.x spec, and follow the Configure MCP guide for the MCP extensions.-

Execution Workflow and Validation Loop

  1. Get the current spec:

    • Use the spec file in the user's repository. If there is no file, find the active API config of the gateway:

      gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(apiConfig)"
    • The output is projects/{project}/locations/global/apis/{api_id}/configs/{config_id}. Print the spec of that config:

      gcloud api-gateway api-configs describe {config_id} --api={api_id} --project={project_id} --view=FULL \
        --format="value(openapiDocuments[0].document.contents)" | tr '_-' '/+' | base64 --decode
    • gcloud prints the contents in URL-safe base64, so tr changes two characters before base64 --decode. If the config has more than one OpenAPI document, change [0] to [1], [2], and so on.

  2. Write the OpenAPI 3.x spec:

    • For an OpenAPI 2.0 spec, follow OpenAPI 2.0 to 3.x Migration, and compare your result with its complete converted example.

    • For a new spec, start from the template in Extensions and Limits.

    • Set openapi to a 3.0.x or 3.1.x version. The examples use 3.0.4. In OpenAPI 3.1, give each schema one type. Rationale: API Gateway rejects a type list such as type: ["string", "null"].

    • Give every operation a unique operationId and a responses object, and use only local $ref values. Rationale: API Gateway rejects an operation without operationId or responses, two operationId values that give the same method name, such as getItem and get-Item, and a $ref to a URL.

  3. Run the deterministic validation loop on every spec that you write or change, before you answer or create the API config:

    python3 scripts/validate_apigw_openapi.py --spec={spec_file}
    • The script path is relative to the directory of this skill. If you only return the spec in your reply, write it to a temporary file, and run the script on that file before you answer.

    • If the script exits with code 1 ("status": "FAIL"), fix every error in {spec_file}, and run the script again. Continue until it exits with code 0 ("status": "PASS").

    • If the script exits with code 2, fix the file path or the YAML/JSON syntax error that stderr shows, or install PyYAML.

    • Read every warning, such as a backend without pathTranslation, a quota on an operation without an API key, or allowCors. Fix it, or tell the user why you keep it.

    • The script does not check every rule. A PASS means that it found none of the API Gateway problems that this skill describes. It does not check general OpenAPI validity, such as a $ref to a schema that does not exist. Rationale: only api-configs create in step 5 shows that API Gateway accepts the spec. Do not tell the user that the spec deploys because the script passed.

  4. Summarize the spec for the user, and get approval before you deploy. State each of these points:

    • Each OpenAPI 2.0 extension that you moved or removed, such as x-google-allow, which OpenAPI 3.x does not support. Also state each other change, such as an added operationId or a fixed address.

    • The pathTranslation of each backend (backend_path_translation in the script output), and each operation whose path parameters now go to the backend as query parameters (path_parameters_as_query). With APPEND_PATH_TO_ADDRESS, the backend also receives the base path.

    • Which operations need a JWT or an API key, which backends receive an ID token and with which audience, and that API Gateway does not check OAuth scopes.

    • The quota metrics and limits, and that each metric name matches the current API config.

  5. Create a new API config and update the gateway (request human approval before you update a production gateway):

    gcloud api-gateway api-configs create {new_config_id} \
      --api={api_id} \
      --openapi-spec={spec_file} \
      --backend-auth-service-account={gateway_sa_email} \
      --project={project_id}
    
    gcloud api-gateway gateways update {gateway_id} \
      --api={api_id} \
      --api-config={new_config_id} \
      --location={region} \
      --project={project_id}
    • For a new gateway, run gcloud api-gateway gateways create {gateway_id} with the same flags instead of gateways update. api-configs create creates the API if it does not exist.

    • If an operation requires an API key, enable the managed service of the API. Get its name with gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)", and then run gcloud services enable {managed_service} --project={project_id}. Also enable it in each project that creates API keys for the API.

    • Use a new config ID for each change, because you cannot change the spec of an existing API config.

    • Run one api-configs create at a time for each API, and wait for it to finish. A large API config can take up to ten minutes to create.

    • If api-configs create fails, find the error text in API Config Errors, fix the spec, and go back to step 3.

    • Keep the previous API config until the new one serves traffic. To roll back, run gateways update with the previous config ID.

  6. Verify the gateway:

    • Run gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(state,defaultHostname)", and wait until the state is ACTIVE.

    • Send a request to each changed path at https://{default_hostname}{base_path}{path}, with the credential that the operation requires. Check that the backend receives the path and parameters that you expect.

    • An HTML 404 Page not found means that the gateway is not ready. Check that the last create or update finished, and retry before you change the config. During a gateway update, some requests can still reach the previous API config. A JSON 404 (The current request is not defined by this API.) means that the active API config does not define the path.

Pre-Deployment Checklist

  • [ ] openapi is 3.0.x or 3.1.x, and the spec has no OpenAPI 2.0 extension, such as x-google-management, x-google-endpoints, x-google-api-name, x-google-allow, or x-google-issuer on a security scheme.

  • [ ] x-google-api-management.backends defines every backend, every x-google-backend is a string that names one, and no path item sets x-google-backend.

  • [ ] Every backend sets pathTranslation.

  • [ ] Every operation has a unique operationId and a responses object, and each path variable has a parameter with in: path and required: true.

  • [ ] Every x-google-quota is on an operation that requires an API key, and every metric name matches the current API config.

  • [ ] At most one servers entry has x-google-endpoint, and its URL has no custom port.

  • [ ] python3 scripts/validate_apigw_openapi.py --spec={spec_file} returns "status": "PASS" (exit code 0).

Resource Cleanup

To avoid ongoing charges when you tear down a test environment, request human approval, and delete the resources in dependency order:

gcloud api-gateway gateways delete {gateway_id} --location={region} --project={project_id}
gcloud api-gateway api-configs delete {config_id} --api={api_id} --project={project_id}
gcloud api-gateway apis delete {api_id} --project={project_id}

Files

references/openapi-2-to-3-migration.md

OpenAPI 2.0 to 3.x Migration for API Gateway

  • Migration Steps: Lines 9-18

  • Extension Mapping Table: Lines 20-35

  • Extension Examples: Lines 37-151

  • Swagger 2.0 Construct Conversion Map: Lines 153-170

  • Complete Converted Example: Lines 172-384

Migration Steps

  1. Get the OpenAPI 2.0 spec: the file in the user's repository, or the spec of the active API config of the gateway (see step 1 of the workflow in SKILL.md). If the spec has no x-google-backend, ask the user for the backend URL. Do not invent an address.

  2. Convert the standard fields. The conversion utility in Swagger Editor changes swagger to openapi, securityDefinitions to components.securitySchemes, definitions to components.schemas, and in: body parameters to requestBody. To convert by hand, use the Swagger 2.0 Construct Conversion Map.

  3. Move each Google extension with the Extension Mapping Table. Rationale: a converter leaves every x-google-* extension in its OpenAPI 2.0 form, and API Gateway rejects most of them in an OpenAPI 3.x spec.

  4. Add x-google-endpoint: {} to the servers entry that has the base path. Rationale: a converter writes servers without x-google-endpoint, and API Gateway ignores such entries, so calls to the base path return HTTP 404.

  5. Set pathTranslation on every backend. Keep the behavior of the OpenAPI 2.0 spec: OpenAPI 2.0 has the same defaults (APPEND_PATH_TO_ADDRESS for a root backend, CONSTANT_ADDRESS for an operation-level backend).

  6. Run python3 scripts/validate_apigw_openapi.py --spec={spec_file}. Fix every error. Fix every warning, or tell the user why you keep it.

Reference: Modify a gateway to use OpenAPI 3.x

Extension Mapping Table

FeatureOpenAPI 2.0OpenAPI 3.xRequired change
BackendsInline x-google-backend object at the root or on an operation, with snake_case fields (address, jwt_audience, disable_auth, path_translation, deadline, protocol)Root x-google-api-management.backends.{backend_name} with camelCase fields (address, jwtAudience, disableAuth, pathTranslation, deadline, protocol) + x-google-backend: {backend_name}Define one named backend for each distinct backend object, and replace each object with the name. Compare all fields, not only address. If the root and an operation use the same object without path_translation, define two backends: one with APPEND_PATH_TO_ADDRESS for the root, and one with CONSTANT_ADDRESS for the operation. API Gateway rejects an inline object in OpenAPI 3.x.
JWT authenticationx-google-issuer, x-google-jwks_uri, x-google-audiences (a comma-separated string), and x-google-jwt-locations on the security definition. Older specs use x-issuer and x-jwks_uri.x-google-auth: {issuer, jwksUri, audiences, jwtLocations} in components.securitySchemes.{scheme_name}Nest the values in x-google-auth. Change audiences to a YAML list: split the string at the commas, and remove the spaces. In each JWT location, value_prefix becomes valuePrefix.
API keysecurityDefinitions entry with type: apiKeycomponents.securitySchemes entry with type: apiKeyNo change other than the move.
Metrics and quota limitsx-google-management.metrics and quota.limits lists, with name, valueType, metricKind, unit, and values: {STANDARD: N}x-google-api-management.metrics and quota.limits maps, keyed by name, with values: NMake each list a map keyed by the old name. Keep only displayName on each metric, and only metric and values on each limit. API Gateway rejects the other fields, such as valueType, metricKind, and unit, and it uses the unit 1/min/{project}. Keep each metric name exactly the same.
Quota costx-google-quota: {metricCosts: {metric_name: cost}}x-google-quota: {metric_name: cost} on each operationRemove the metricCosts wrapper. In OpenAPI 3.x, API Gateway ignores x-google-quota at the root or path level.
Base pathbasePathservers: [{url: {basePath}, x-google-endpoint: {}}]Make sure that one servers entry has x-google-endpoint, even an empty {}. A converter does not add it.
Endpoint and CORSRoot x-google-endpoints: [{name, allowCors}]servers: [{url, x-google-endpoint: {allowCors}}]Move allowCors (and target, if set) to one servers entry, and remove name.
API namex-google-api-namex-google-api-management.apiNameMove the value.
Catch-all routingx-google-allow: allNot supportedRemove it, and list every path. To forward every other path as OpenAPI 2.0 did, see the x-google-allow row of the Swagger 2.0 Construct Conversion Map.
Other OpenAPI 2.0 extensionsx-google-deprecated, x-google-experimental-authorization, x-google-backend-url, x-google-backend-deadline, and x-securityNot supportedRemove x-google-deprecated and x-google-experimental-authorization. Move a backend URL or deadline to x-google-api-management.backends, and move x-security to the OpenAPI security field.

Reference: OpenAPI 3.x extensions in API Gateway

Extension Examples

Backend, OpenAPI 2.0:

x-google-backend:
  address: https://orders-abc123-uc.a.run.app
  path_translation: APPEND_PATH_TO_ADDRESS

Backend, OpenAPI 3.x:

x-google-api-management:
  backends:
    orders-backend:
      address: https://orders-abc123-uc.a.run.app
      pathTranslation: APPEND_PATH_TO_ADDRESS
x-google-backend: orders-backend

JWT scheme, OpenAPI 2.0:

securityDefinitions:
  firebase:
    type: oauth2
    flow: implicit
    authorizationUrl: ""
    x-google-issuer: "https://securetoken.google.com/{firebase_project_id}"
    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
    x-google-audiences: "{firebase_project_id}"

JWT scheme, OpenAPI 3.x:

components:
  securitySchemes:
    firebase:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: ""
          scopes: {}
      x-google-auth:
        issuer: "https://securetoken.google.com/{firebase_project_id}"
        jwksUri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
        audiences:
          - "{firebase_project_id}"

Quota, OpenAPI 2.0:

x-google-management:
  metrics:
    - name: read-requests
      displayName: Read requests
      valueType: INT64
      metricKind: DELTA
  quota:
    limits:
      - name: read-limit
        metric: read-requests
        unit: "1/min/{project}"
        values:
          STANDARD: 600
paths:
  /orders:
    get:
      x-google-quota:
        metricCosts:
          read-requests: 1

Quota, OpenAPI 3.x:

x-google-api-management:
  metrics:
    read-requests:
      displayName: Read requests
  quota:
    limits:
      read-limit:
        metric: read-requests
        values: 600
paths:
  /orders:
    get:
      x-google-quota:
        read-requests: 1

Endpoint, base path, and API name, OpenAPI 2.0:

basePath: /v1
x-google-endpoints:
  - name: "orders-api-1a2b3c.apigateway.{project_id}.cloud.goog"
    allowCors: true
x-google-api-name: orders

Endpoint, base path, and API name, OpenAPI 3.x:

servers:
  - url: /v1
    x-google-endpoint:
      allowCors: true
x-google-api-management:
  apiName: orders

Swagger 2.0 Construct Conversion Map

Swagger 2.0 constructOpenAPI 3.x for API Gateway
host, basePath: /v1, and schemesservers: [{url: /v1, x-google-endpoint: {}}]. Remove host and schemes. Use url: https://{managed_service}/v1 instead if the API uses a managed service that you chose, and not the default *.apigateway.{project_id}.cloud.goog service, because API Gateway then reads the service name from the URL host. Use it also if the user shares the spec with API consumers. {managed_service} is the output of gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)".
Root x-google-backend objectA named backend in x-google-api-management.backends + root x-google-backend: {backend_name}.
Operation x-google-backend objectA named backend + operation x-google-backend: {backend_name}. If the object has no path_translation, set pathTranslation: CONSTANT_ADDRESS to keep the OpenAPI 2.0 behavior. Do not share this backend with the root if the root object has no path_translation either.
in: body parameterrequestBody.content.application/json.schema.
in: formData parametersrequestBody with the application/x-www-form-urlencoded or multipart/form-data media type.
Parameter type, format, and itemsMove them into the parameter schema.
collectionFormat: csvstyle: form and explode: false (query), or style: simple (path or header), with an array schema of a primitive type. API Gateway does not check or split the value. The backend gets the comma-separated string and must parse it.
definitions and #/definitions/{name}components.schemas and #/components/schemas/{name}.
Root parameters and responsescomponents.parameters and components.responses.
securityDefinitionscomponents.securitySchemes. An oauth2 flow: implicit with authorizationUrl: {url} becomes flows: {implicit: {authorizationUrl: {url}, scopes: {}}}. Map accessCode to authorizationCode, application to clientCredentials, and password to password, and keep tokenUrl.
consumes and producesThe media types in requestBody.content and in each responses.{code}.content.
Response schemaresponses.{code}.content.application/json.schema. You can quote each status code key, such as "200", to keep the keys strings.
Path template {name=**}{name}, with x-google-parameter: {pattern: "**"} on the path parameter. OpenAPI 3.x rejects the {name=*} and {name=**} syntax.
x-google-allow: allRemove it. To keep the OpenAPI 2.0 behavior, add a path such as /{path} whose path parameter has in: path, required: true, and x-google-parameter: {pattern: "**"}. Add one operation for each of get, post, put, patch, and delete, each with a unique operationId and security: []. Rationale: OpenAPI 2.0 passed these calls to the backend without an API key or a JWT. Remove security: [] only if the user wants the gateway to check credentials on these paths.

Complete Converted Example

The OpenAPI 2.0 input has a base path, a root Cloud Run backend, an operation-level Cloud Run functions backend, an API key, a Firebase JWT, a quota, and x-google-allow:

swagger: "2.0"
info:
  title: Inventory API
  version: 1.2.0
host: "inventory-api-1a2b3c.apigateway.{project_id}.cloud.goog"
basePath: /v1
schemes:
  - https
x-google-allow: all
x-google-backend:
  address: https://inventory-abc123-uc.a.run.app
  path_translation: APPEND_PATH_TO_ADDRESS
  deadline: 30.0
x-google-management:
  metrics:
    - name: read-requests
      displayName: Read requests
      valueType: INT64
      metricKind: DELTA
  quota:
    limits:
      - name: read-limit
        metric: read-requests
        unit: "1/min/{project}"
        values:
          STANDARD: 600
securityDefinitions:
  api_key:
    type: apiKey
    name: key
    in: query
  firebase:
    type: oauth2
    flow: implicit
    authorizationUrl: ""
    x-google-issuer: "https://securetoken.google.com/{firebase_project_id}"
    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
    x-google-audiences: "{firebase_project_id}"
security:
  - api_key: []
paths:
  /items/{itemId}:
    get:
      operationId: getItem
      x-google-quota:
        metricCosts:
          read-requests: 1
      parameters:
        - name: itemId
          in: path
          required: true
          type: string
      responses:
        200:
          description: The item.
          schema:
            $ref: "#/definitions/Item"
  /items:
    post:
      operationId: createItem
      security:
        - api_key: []
          firebase: []
      parameters:
        - name: item
          in: body
          required: true
          schema:
            $ref: "#/definitions/Item"
      responses:
        200:
          description: The created item.
          schema:
            $ref: "#/definitions/Item"
  /reports/daily:
    get:
      operationId: getDailyReport
      x-google-backend:
        address: "https://us-central1-{project_id}.cloudfunctions.net/dailyReport"
      responses:
        200:
          description: The daily report.
definitions:
  Item:
    type: object
    required:
      - sku
    properties:
      sku:
        type: string
      quantity:
        type: integer
        format: int32

The OpenAPI 3.x output:

openapi: 3.0.4
info:
  title: Inventory API
  version: 1.2.0
servers:
  - url: /v1
    x-google-endpoint: {}
x-google-api-management:
  backends:
    inventory-backend:
      address: https://inventory-abc123-uc.a.run.app
      pathTranslation: APPEND_PATH_TO_ADDRESS
      deadline: 30.0
    daily-report-fn:
      address: "https://us-central1-{project_id}.cloudfunctions.net/dailyReport"
      pathTranslation: CONSTANT_ADDRESS
  metrics:
    read-requests:
      displayName: Read requests
  quota:
    limits:
      read-limit:
        metric: read-requests
        values: 600
x-google-backend: inventory-backend
security:
  - api_key: []
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: key
      in: query
    firebase:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: ""
          scopes: {}
      x-google-auth:
        issuer: "https://securetoken.google.com/{firebase_project_id}"
        jwksUri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
        audiences:
          - "{firebase_project_id}"
  schemas:
    Item:
      type: object
      required:
        - sku
      properties:
        sku:
          type: string
        quantity:
          type: integer
          format: int32
paths:
  /items/{itemId}:
    get:
      operationId: getItem
      x-google-quota:
        read-requests: 1
      parameters:
        - name: itemId
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: The item.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Item"
  /items:
    post:
      operationId: createItem
      security:
        - api_key: []
          firebase: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Item"
      responses:
        "200":
          description: The created item.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Item"
  /reports/daily:
    get:
      operationId: getDailyReport
      x-google-backend: daily-report-fn
      responses:
        "200":
          description: The daily report.

What changed:

  • x-google-allow is gone. The spec lists every path that clients call. Requests to other paths now return HTTP 404. In OpenAPI 2.0, they went to the backend without an API key.

  • host, basePath, and schemes became one servers entry with x-google-endpoint.

  • Each inline x-google-backend object became a named backend. The Cloud Run functions backend sets pathTranslation: CONSTANT_ADDRESS, which is the OpenAPI 2.0 default for an operation-level backend.

  • The metrics and limits became maps without valueType, metricKind, and unit, and x-google-quota lost its metricCosts wrapper. The metric name read-requests did not change. getItem keeps its API key requirement from the root security, because API Gateway uses the API key to identify the consumer project for the quota.

  • The JWT settings moved into x-google-auth, and audiences became a list.

  • in: body became requestBody, definitions became components.schemas, and each response schema moved into content.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an API key, Needs a command-line tool, Needs Python

Security

What our scanner noticed· Low risk

  • Instructions that use the network
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Google
Publisher
Google (Official)
Source
google/skills · skills/cloud/api-gateway-openapi-spec-authoring · commit 2194d3b
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Google or Google.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download api-gateway-openapi-spec-authoring.zip