OpenAPI extensions

Cloud Endpoints accepts a set of Google-specific extensions to the OpenAPI specification that configure the behaviors of the Extensible Service Proxy (ESP) and Service Control. This page describes Google- specific extensions to the OpenAPI specification.

Although the examples given below are in YAML format, JSON is also supported.

Naming convention

Google OpenAPI extensions have names that begin with the x-google- prefix.


x-google-allow: [configured | all]

This extension is used at the top level of an OpenAPI specification to indicate what URL paths should be allowed through ESP.

Possible values are configured and all.

The default value is configured, which means that only the API methods that you have listed in your OpenAPI specification are served through ESP.

When all is used, unconfigured calls—with or without an API key or user authentication—pass through ESP to your API.

ESP processes calls to your API in a case-sensitive manner. For example, ESP considers /widgets and /Widgets as different API methods.

When all is used, you need to take extra care in two areas:

  • Any API key or authentication rules.
  • The backend path routing in your service.

As a best practice, we recommend that you configure your API to use case-sensitive path routing. By using case-sensitive routing, your API returns an HTTP status code of 404 when the method requested in the URL doesn't match the API method name listed in your OpenAPI specification. Note that web application frameworks such as Node.js Express have a setting to enable or disable case-sensitive routing. The default behavior depends on the framework that you are using. We recommend that you review the settings in your framework to make sure that case-sensitive routing is enabled. This recommendation agrees with the OpenAPI Specification v2.0 that says: "All field names in the specification are case sensitive."


Assume that:

  • x-google-allow is set to all.
  • The API method widgets is listed in your OpenAPI specification but not Widgets.
  • You have configured your OpenAPI specification to require an API key.

Because widgets is listed in your OpenAPI specification, ESP blocks the following request because it doesn't have an API key:

Because Widgets isn't listed in your OpenAPI specification, ESP passes the following request through to your service without an API key:

If your API uses case-sensitive routing (and you haven't routed calls to "Widgets" to any code), your API backend returns a 404. If, however, you are using case-insensitive routing, your API backend routes this call to "widgets."

Different languages and frameworks have different methods for controlling case sensitivity and routing. Consult the documentation for your framework for details.


The x-google-backend extension can be specified at the top level and/or operation level of an OpenAPI specification, to control various parts of backend routing. ESP is configured with a single target backend using the --backend flag (defaults to when not configured), and when ESP starts, all traffic is sent to that target. But there are a couple of situations where sending traffic to a single backend isn't sufficient:

  • Whenever you can't control the ESP target backend location, such as when you're using Cloud Functions or Cloud Run.
  • Whenever your API targets multiple backends.

x-google-backend contains the following fields:


address: URL

Required. The URL of the target backend.

jwt_audience | disable_auth

jwt_audience: STRING

Optional. The JWT audience specified when ESP obtains an instance id token, which is then used when making the target backend request.

disable_auth: BOOL

Optional. When you do not want use IAP or IAM as your target backend authentication, set it to be true.

When neither of jwt_audience and disable_auth is set or disable_auth is set as false, the audience will be same as theaddress field and an ID token with the audience will be added to the request Authorization header.

If a request has the Authorization header, its value will be copied to a new header X-Forwarded-Authorization if ESP needs to over-write it.



Optional. Sets the path translation strategy used by ESP when making target backend requests.


deadline: DOUBLE

Optional. The number of seconds to wait for a full response from a request. Responses that take longer than the configured deadline will time out. The default deadline is 15.0 seconds.

Non-positive values will not be honored. ESPv2 Beta will automatically use the default value in these cases.

The deadline cannot be disabled, but it can be set to a high number — for example, 3600.0 for one hour.


protocol: STRING

Optional. The protocol used for sending a request to the backend. The supported values are http/1.1 and h2.

The default value is http/1.1 for HTTP and HTTPS backends.

For secure HTTP backends (https://) that support HTTP/2, set this field to h2 for improved performance.

Enabling backends support in ESP

Enable x-google-backend support in ESP by providing the --enable_backend_routing argument when running ESP container. (For the runtimes where you do not control the ESP container options, this option is already provided for you.) Following is an example of enabling x-google-backend support when deploying the ESP container onto GKE (this example builds on the Endpoints on GKE Tutorial example):

- name: esp
  args: [
    "--http_port", "8081",
    "--service", "SERVICE_NAME",
    "--rollout_strategy", "managed",

Understanding path translation

As ESP handles requests, it will take the original request path and translate it prior to making a request to the target backend. Exactly how this translation occurs depends on which path translation strategy you are using. There are two path translation strategies:

  • APPEND_PATH_TO_ADDRESS: The target backend request path is computed by appending the original request path to the address URL of the x-google-backend extension.
  • CONSTANT_ADDRESS: The target request path is constant, as defined by the address URL of the x-google-backend extension. If the corresponding OpenAPI path contains parameters, the parameter name and its value become query parameters.


    • address:
    • With OpenAPI path parameters
      • OpenAPI path: /hello/{name}
      • Request path: /hello/world
      • Target request URL:
    • Without OpenAPI path parameters
      • OpenAPI path: /hello
      • Request path: /hello
      • Target request URL:
    • address:
    • With OpenAPI path parameters
      • OpenAPI path: /hello/{name}
      • Request path: /hello/world
      • Target request URL:
    • Without OpenAPI path parameters
      • OpenAPI path: /hello
      • Request path: /hello
      • Target request URL:


This section describes the uses of the x-google-endpoints extension.

Configuring DNS on the domain

If you have deployed your application to Compute Engine or Google Kubernetes Engine, you can create a DNS entry for your Endpoints service on the domain by adding the following to your OpenAPI document:

- name: ""
  target: "IP_ADDRESS"

Add the x-google-endpoints extension at the top level of your OpenAPI document (not indented or nested). You must configure the domain name in the format:

For example:

swagger: "2.0"
host: ""
- name: ""
  target: ""

The domain is managed by Google and shared by Google Cloud customers. Because Google Cloud project IDs are globally unique, a domain name in the format is a unique domain name for your API.

For simplicity, configure the host field and the field to be the same. When you deploy your OpenAPI document, Service Management creates:

  • A managed service with the name that you've specified in the host field.
  • A DNS A-record using the name and IP address that you configured in the x-google-endpoints extension.

For APIs that are hosted on the App Engine flexible environment, you can use the domain. For more information, see Configuring Endpoints.

Configuring ESP to allow CORS requests

If your API is called from a web application on a different origin, your API must support Cross-Origin Resource Sharing (CORS). See Adding CORS support to ESP for information on configuring ESP to support CORS.

If you need to implement custom CORS support in your backend code, set allowCors: True so that ESP passes all CORS requests through to your backend code:

- name: ""
  allowCors: True

Add the x-google-endpoints extension at the top level of your OpenAPI document (not indented or nested), for example:

swagger: "2.0"
host: ""
- name: ""
  allowCors: True


x-google-issuer: URI | EMAIL_ADDRESS

This extension is used in the OpenAPI securityDefinitions section to specify the issuer of a credential. Values can take the form of a hostname or email address.


x-google-jwks_uri: URI

URI of the provider's public key set to validate the signature of the JSON Web Token.

ESP supports two asymmetric public key formats defined by the x-google-jwks_uri OpenAPI extension:

  • JWK set format. For example:
    x-google-jwks_uri: "https://YOUR_ACCOUNT_NAME.YOUR_AUTH_PROVIDER_URL/.well-known/jwks.json"
  • X509. For example:
    x-google-jwks_uri: ""

If you are using a symmetric key format, set x-google-jwks_uri to the URI of a file that contains the base64url-encoded key string.

If you omit x-google-jwks_uri, ESP will follow the OpenID Connect Discovery protocol to automatically discover the JWKS URI for the given OpenID provider. ESP will make a request to x-google-issuer/.well-known/openid-configuration, parse the JSON response, and read the JWKS URI from the top-level jwks_uri field.

Note that omitting x-google-jwks_uri will result in higher cold start times, as ESP has to make an extra remote call on startup. Therefore, it is only recommended to omit this field if the JWKS URI changes often. Most certified OpenID providers (such as Google, Auth0, and Okta) have stable JWKS URIs.


By default, a JWT is passed either in the Authorization header (prefixed by "Bearer "), X-Goog-Iap-Jwt-Assertion header, or in the access_token query parameter. See Making an authenticated call to an Endpoints API for examples on passing a JWT.

Alternatively, use the x-google-jwt-locations extension in the OpenAPI securityDefinitions section to provide the customized locations from where to extract the JWT token.

The x-google-jwt-locations extension accepts a list of JWT locations. Each JWT location contains the following fields:

Element Description
header/query Required. The name for the header containing the JWT, or the name for the query parameter containing the JWT.
value_prefix Optional. For header only. When the value_prefix is set, its value must match the prefix of the header value containing the JWT.

For example:

  # Expect header "Authorization": "MyBearerToken <TOKEN>"
  - header: "Authorization"
    value_prefix: "MyBearerToken "
  # expect header "jwt-header-foo": "jwt-prefix-foo<TOKEN>"
  - header: "jwt-header-foo"
    value_prefix: "jwt-prefix-foo"
  # expect header "jwt-header-bar": "<TOKEN>"
  - header: "jwt-header-bar"
  # expect query parameter "jwt_query_bar=<TOKEN>"
  - query: "jwt_query_bar"

If you want to support only a subset of the default JWT locations, list them out explicitly in the x-google-jwt-locations extension. For example, to include support for only the Authorization header with the "Bearer " prefix:

    # Support the default header "Authorization": "Bearer <TOKEN>"
    - header: "Authorization"
      value_prefix: "Bearer "


x-google-audiences: STRING

This extension is used in the OpenAPI securityDefinitions section to provide a list of audiences the API accepts. This extension accepts a single string with values separated by a comma. Spaces aren't allowed between the audiences.

    type: oauth2
    authorizationUrl: ""
    flow: implicit
    x-google-issuer: ""
    x-google-jwks_uri: ""
    x-google-audiences: ","


The x-google-management extension controls different aspects of API management and contains the fields described in this section.


You use metrics in conjunction with quota and x-google-quota to configure a quota for your API. A quota lets you control the rate at which applications can call the methods in your API. For example:

    - name: read-requests
      displayName: Read requests
      valueType: INT64
      metricKind: DELTA

The metrics field contains a list with the following key-value pairs:

Element Description
name Required. The name for this metric. Typically, this is the type of request (for example, "read-requests" or "write-requests") that uniquely identifies the metric.

Optional, but recommended. The text displayed to identify the metric on the Quotas tab on the Endpoints > Services page in the Cloud Console. This text is also displayed to consumers of your API on the Quotas pages under IAM & admin and APIs & Services. The display name must be a maximum of 40 characters.

For readability purposes, the unit from the associated quota limit is automatically appended to the display name in the Cloud Console. For example, if you specify "Read requests" for the display name, then "Read requests per minute per project" is displayed in the Cloud Console. If not specified, "unlabeled quota" is displayed to the consumers of your API on the Quotas pages under IAM & admin and APIs & Services.

To maintain consistency with the display names of Google services listed on the Quotaspage that consumers of your API see, we recommend the following for the display name:

  • Use "Requests" when you have only one metric.
  • When you have multiple metrics, each should describe the type of request and contain the word "requests" (for example "Read requests" or "Write requests").
  • Use "quota units" instead of "requests" when any of the costs associated with the metric is greater than 1.
valueType Required. Must be INT64
metricKind Required. Must be DELTA


You specify the quota limit for a defined metric in the quota section. For example:

    - name: read-requests-limit
      metric: read-requests
      unit: 1/min/{project}
        STANDARD: 5000

The quota.limits field contains a list with the following key:value pairs:

Element Description
name Required. Name of the limit, which must be unique within the service The name can contain lower and upper case letters, numbers and `-` (the dash character), and it must have a maximum length of 64 characters.
metric Required. The name of the metric this limit applies to. This name must match the text specified in the name of a metric. If the specified text doesn't match a metric name, you get an error when you deploy your OpenAPI document.
unit Required. The unit of the limit. Currently only "1/min/{project}" is supported, which means that the limit is enforced per-project and the usage is reset every minute.
values Required. The limit for the metric. You must specify this as a key:value pair, in the following format:
You replace YOUR-LIMIT-FOR-THE-METRIC with an integer value that is the maximum number of requests allowed for the specified unit (which is currently only per-minute, per-project). For example:
  STANDARD: 5000


The x-google-quota extension is used in the OpenAPI paths section to associate a method in your API with a metric. Methods that don't have x-google-quota defined don't have quota limits applied to them. For example:

    read-requests: 1

The x-google-quota extension contains the following item:

Element Description
metricCosts A user-defined key:value pair: "YOUR-METRIC-NAME": METRIC-COST.
  • "YOUR-METRIC-NAME": The text for "YOUR-METRIC-NAME" must match a defined metric name.
  • METRIC-COST: An integer value that defines the cost for each request. When a request is made, the associated metric is incremented by the specified cost. The cost allows methods to consume at different rates from the same metric. For example, if a metric has a quota limit of 1000 and a cost of 1, the calling application can make 1000 requests per minute before going over the limit. With a cost of 2 for the same metric, a calling application can make only 500 requests per minute before going over the limit.

Quota examples

The following example shows adding a metric and limit for read requests and write requests.

    # Define a metric for read requests.
    - name: "read-requests"
      displayName: "Read requests"
      valueType: INT64
      metricKind: DELTA
    # Define a metric for write requests.
    - name: "write-requests"
      displayName: "Write requests"
      valueType: INT64
      metricKind: DELTA
      # Rate limit for read requests.
      - name: "read-requests-limit"
        metric: "read-requests"
        unit: "1/min/{project}"
          STANDARD: 5000
      # Rate limit for write requests.
      - name: "write-request-limit"
        metric: "write-requests"
        unit: "1/min/{project}"
          STANDARD: 5000

      description: "Echo back a given message."
      operationId: "echo"
      - "application/json"
          description: "Echo"
            $ref: "#/definitions/echoMessage"
      - description: "Message to echo"
        in: body
        name: message
        required: true
          $ref: "#/definitions/echoMessage"
          read-requests: 1
      - api_key: []


When your service contains only one API, the API name is the same as the Endpoints service name. (Endpoints uses the name you specify in the host field of your OpenAPI document as the name of your service.) When your service contains more than one API, you specify the API names by adding the x-google-api-name extension to your OpenAPI document. The x-google-api-name extension allows you to explicitly name individual APIs and establish independent versioning for each API.

For example, you can configure a service named with two APIs, producer and consumer, with the OpenAPI document fragments below:

  • Producer API in producer.yaml:

    swagger: 2.0
    x-google-api-name: producer
      version: 1.0.3

  • Consumer API in consumer.yaml:

    swagger: 2.0
    x-google-api-name: consumer
      version: 1.1.0

You can deploy the two OpenAPI documents jointly with:

gcloud endpoints services deploy producer.yaml consumer.yaml