diff --git a/apigateway/apiv1/api_gateway_client.go b/apigateway/apiv1/api_gateway_client.go
new file mode 100644
index 0000000..464a81c
--- /dev/null
+++ b/apigateway/apiv1/api_gateway_client.go
@@ -0,0 +1,1402 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package apigateway
+
+import (
+	"context"
+	"fmt"
+	"math"
+	"net/url"
+	"time"
+
+	"cloud.google.com/go/longrunning"
+	lroauto "cloud.google.com/go/longrunning/autogen"
+	"github.com/golang/protobuf/proto"
+	gax "github.com/googleapis/gax-go/v2"
+	"google.golang.org/api/iterator"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	gtransport "google.golang.org/api/transport/grpc"
+	apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/metadata"
+)
+
+var newClientHook clientHook
+
+// CallOptions contains the retry settings for each method of Client.
+type CallOptions struct {
+	ListGateways    []gax.CallOption
+	GetGateway      []gax.CallOption
+	CreateGateway   []gax.CallOption
+	UpdateGateway   []gax.CallOption
+	DeleteGateway   []gax.CallOption
+	ListApis        []gax.CallOption
+	GetApi          []gax.CallOption
+	CreateApi       []gax.CallOption
+	UpdateApi       []gax.CallOption
+	DeleteApi       []gax.CallOption
+	ListApiConfigs  []gax.CallOption
+	GetApiConfig    []gax.CallOption
+	CreateApiConfig []gax.CallOption
+	UpdateApiConfig []gax.CallOption
+	DeleteApiConfig []gax.CallOption
+}
+
+func defaultClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("apigateway.googleapis.com:443"),
+		internaloption.WithDefaultMTLSEndpoint("apigateway.mtls.googleapis.com:443"),
+		internaloption.WithDefaultAudience("https://apigateway.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+		option.WithGRPCDialOption(grpc.WithDisableServiceConfig()),
+		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
+			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
+	}
+}
+
+func defaultCallOptions() *CallOptions {
+	return &CallOptions{
+		ListGateways: []gax.CallOption{},
+		GetGateway:   []gax.CallOption{},
+		CreateGateway: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		UpdateGateway: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		DeleteGateway: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		ListApis: []gax.CallOption{},
+		GetApi:   []gax.CallOption{},
+		CreateApi: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		UpdateApi: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		DeleteApi: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		ListApiConfigs: []gax.CallOption{},
+		GetApiConfig:   []gax.CallOption{},
+		CreateApiConfig: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		UpdateApiConfig: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+		DeleteApiConfig: []gax.CallOption{
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unknown,
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        60000 * time.Millisecond,
+					Multiplier: 2.00,
+				})
+			}),
+		},
+	}
+}
+
+// Client is a client for interacting with API Gateway API.
+//
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type Client struct {
+	// Connection pool of gRPC connections to the service.
+	connPool gtransport.ConnPool
+
+	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
+	disableDeadlines bool
+
+	// The gRPC API client.
+	client apigatewaypb.ApiGatewayServiceClient
+
+	// LROClient is used internally to handle longrunning operations.
+	// It is exposed so that its CallOptions can be modified if required.
+	// Users should not Close this client.
+	LROClient *lroauto.OperationsClient
+
+	// The call options for this service.
+	CallOptions *CallOptions
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogMetadata metadata.MD
+}
+
+// NewClient creates a new api gateway service client.
+//
+// The API Gateway Service is the interface for managing API Gateways.
+func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
+	clientOpts := defaultClientOptions()
+
+	if newClientHook != nil {
+		hookOpts, err := newClientHook(ctx, clientHookParams{})
+		if err != nil {
+			return nil, err
+		}
+		clientOpts = append(clientOpts, hookOpts...)
+	}
+
+	disableDeadlines, err := checkDisableDeadlines()
+	if err != nil {
+		return nil, err
+	}
+
+	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
+	if err != nil {
+		return nil, err
+	}
+	c := &Client{
+		connPool:         connPool,
+		disableDeadlines: disableDeadlines,
+		CallOptions:      defaultCallOptions(),
+
+		client: apigatewaypb.NewApiGatewayServiceClient(connPool),
+	}
+	c.setGoogleClientInfo()
+
+	c.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool))
+	if err != nil {
+		// This error "should not happen", since we are just reusing old connection pool
+		// and never actually need to dial.
+		// If this does happen, we could leak connp. However, we cannot close conn:
+		// If the user invoked the constructor with option.WithGRPCConn,
+		// we would close a connection that's still in use.
+		// TODO: investigate error conditions.
+		return nil, err
+	}
+	return c, nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated.
+func (c *Client) Connection() *grpc.ClientConn {
+	return c.connPool.Conn()
+}
+
+// Close closes the connection to the API service. The user should invoke this when
+// the client is no longer required.
+func (c *Client) Close() error {
+	return c.connPool.Close()
+}
+
+// setGoogleClientInfo sets the name and version of the application in
+// the `x-goog-api-client` header passed on each request. Intended for
+// use by Google-written clients.
+func (c *Client) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", versionGo()}, keyval...)
+	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
+	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
+}
+
+// ListGateways lists Gateways in a given project and location.
+func (c *Client) ListGateways(ctx context.Context, req *apigatewaypb.ListGatewaysRequest, opts ...gax.CallOption) *GatewayIterator {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.ListGateways[0:len(c.CallOptions.ListGateways):len(c.CallOptions.ListGateways)], opts...)
+	it := &GatewayIterator{}
+	req = proto.Clone(req).(*apigatewaypb.ListGatewaysRequest)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*apigatewaypb.Gateway, string, error) {
+		var resp *apigatewaypb.ListGatewaysResponse
+		req.PageToken = pageToken
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = c.client.ListGateways(ctx, req, settings.GRPC...)
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetGateways(), resp.GetNextPageToken(), nil
+	}
+	fetch := func(pageSize int, pageToken string) (string, error) {
+		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+		if err != nil {
+			return "", err
+		}
+		it.items = append(it.items, items...)
+		return nextPageToken, nil
+	}
+	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+	it.pageInfo.MaxSize = int(req.GetPageSize())
+	it.pageInfo.Token = req.GetPageToken()
+	return it
+}
+
+// GetGateway gets details of a single Gateway.
+func (c *Client) GetGateway(ctx context.Context, req *apigatewaypb.GetGatewayRequest, opts ...gax.CallOption) (*apigatewaypb.Gateway, error) {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.GetGateway[0:len(c.CallOptions.GetGateway):len(c.CallOptions.GetGateway)], opts...)
+	var resp *apigatewaypb.Gateway
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.GetGateway(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// CreateGateway creates a new Gateway in a given project and location.
+func (c *Client) CreateGateway(ctx context.Context, req *apigatewaypb.CreateGatewayRequest, opts ...gax.CallOption) (*CreateGatewayOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.CreateGateway[0:len(c.CallOptions.CreateGateway):len(c.CallOptions.CreateGateway)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.CreateGateway(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &CreateGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// UpdateGateway updates the parameters of a single Gateway.
+func (c *Client) UpdateGateway(ctx context.Context, req *apigatewaypb.UpdateGatewayRequest, opts ...gax.CallOption) (*UpdateGatewayOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "gateway.name", url.QueryEscape(req.GetGateway().GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.UpdateGateway[0:len(c.CallOptions.UpdateGateway):len(c.CallOptions.UpdateGateway)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.UpdateGateway(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &UpdateGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// DeleteGateway deletes a single Gateway.
+func (c *Client) DeleteGateway(ctx context.Context, req *apigatewaypb.DeleteGatewayRequest, opts ...gax.CallOption) (*DeleteGatewayOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.DeleteGateway[0:len(c.CallOptions.DeleteGateway):len(c.CallOptions.DeleteGateway)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.DeleteGateway(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &DeleteGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// ListApis lists Apis in a given project and location.
+func (c *Client) ListApis(ctx context.Context, req *apigatewaypb.ListApisRequest, opts ...gax.CallOption) *ApiIterator {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.ListApis[0:len(c.CallOptions.ListApis):len(c.CallOptions.ListApis)], opts...)
+	it := &ApiIterator{}
+	req = proto.Clone(req).(*apigatewaypb.ListApisRequest)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*apigatewaypb.Api, string, error) {
+		var resp *apigatewaypb.ListApisResponse
+		req.PageToken = pageToken
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = c.client.ListApis(ctx, req, settings.GRPC...)
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetApis(), resp.GetNextPageToken(), nil
+	}
+	fetch := func(pageSize int, pageToken string) (string, error) {
+		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+		if err != nil {
+			return "", err
+		}
+		it.items = append(it.items, items...)
+		return nextPageToken, nil
+	}
+	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+	it.pageInfo.MaxSize = int(req.GetPageSize())
+	it.pageInfo.Token = req.GetPageToken()
+	return it
+}
+
+// GetApi gets details of a single Api.
+func (c *Client) GetApi(ctx context.Context, req *apigatewaypb.GetApiRequest, opts ...gax.CallOption) (*apigatewaypb.Api, error) {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.GetApi[0:len(c.CallOptions.GetApi):len(c.CallOptions.GetApi)], opts...)
+	var resp *apigatewaypb.Api
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.GetApi(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// CreateApi creates a new Api in a given project and location.
+func (c *Client) CreateApi(ctx context.Context, req *apigatewaypb.CreateApiRequest, opts ...gax.CallOption) (*CreateApiOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.CreateApi[0:len(c.CallOptions.CreateApi):len(c.CallOptions.CreateApi)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.CreateApi(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &CreateApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// UpdateApi updates the parameters of a single Api.
+func (c *Client) UpdateApi(ctx context.Context, req *apigatewaypb.UpdateApiRequest, opts ...gax.CallOption) (*UpdateApiOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "api.name", url.QueryEscape(req.GetApi().GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.UpdateApi[0:len(c.CallOptions.UpdateApi):len(c.CallOptions.UpdateApi)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.UpdateApi(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &UpdateApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// DeleteApi deletes a single Api.
+func (c *Client) DeleteApi(ctx context.Context, req *apigatewaypb.DeleteApiRequest, opts ...gax.CallOption) (*DeleteApiOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.DeleteApi[0:len(c.CallOptions.DeleteApi):len(c.CallOptions.DeleteApi)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.DeleteApi(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &DeleteApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// ListApiConfigs lists ApiConfigs in a given project and location.
+func (c *Client) ListApiConfigs(ctx context.Context, req *apigatewaypb.ListApiConfigsRequest, opts ...gax.CallOption) *ApiConfigIterator {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.ListApiConfigs[0:len(c.CallOptions.ListApiConfigs):len(c.CallOptions.ListApiConfigs)], opts...)
+	it := &ApiConfigIterator{}
+	req = proto.Clone(req).(*apigatewaypb.ListApiConfigsRequest)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*apigatewaypb.ApiConfig, string, error) {
+		var resp *apigatewaypb.ListApiConfigsResponse
+		req.PageToken = pageToken
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = c.client.ListApiConfigs(ctx, req, settings.GRPC...)
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetApiConfigs(), resp.GetNextPageToken(), nil
+	}
+	fetch := func(pageSize int, pageToken string) (string, error) {
+		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
+		if err != nil {
+			return "", err
+		}
+		it.items = append(it.items, items...)
+		return nextPageToken, nil
+	}
+	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
+	it.pageInfo.MaxSize = int(req.GetPageSize())
+	it.pageInfo.Token = req.GetPageToken()
+	return it
+}
+
+// GetApiConfig gets details of a single ApiConfig.
+func (c *Client) GetApiConfig(ctx context.Context, req *apigatewaypb.GetApiConfigRequest, opts ...gax.CallOption) (*apigatewaypb.ApiConfig, error) {
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.GetApiConfig[0:len(c.CallOptions.GetApiConfig):len(c.CallOptions.GetApiConfig)], opts...)
+	var resp *apigatewaypb.ApiConfig
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.GetApiConfig(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// CreateApiConfig creates a new ApiConfig in a given project and location.
+func (c *Client) CreateApiConfig(ctx context.Context, req *apigatewaypb.CreateApiConfigRequest, opts ...gax.CallOption) (*CreateApiConfigOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.CreateApiConfig[0:len(c.CallOptions.CreateApiConfig):len(c.CallOptions.CreateApiConfig)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.CreateApiConfig(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &CreateApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// UpdateApiConfig updates the parameters of a single ApiConfig.
+func (c *Client) UpdateApiConfig(ctx context.Context, req *apigatewaypb.UpdateApiConfigRequest, opts ...gax.CallOption) (*UpdateApiConfigOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "api_config.name", url.QueryEscape(req.GetApiConfig().GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.UpdateApiConfig[0:len(c.CallOptions.UpdateApiConfig):len(c.CallOptions.UpdateApiConfig)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.UpdateApiConfig(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &UpdateApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// DeleteApiConfig deletes a single ApiConfig.
+func (c *Client) DeleteApiConfig(ctx context.Context, req *apigatewaypb.DeleteApiConfigRequest, opts ...gax.CallOption) (*DeleteApiConfigOperation, error) {
+	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
+		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
+		defer cancel()
+		ctx = cctx
+	}
+	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
+	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
+	opts = append(c.CallOptions.DeleteApiConfig[0:len(c.CallOptions.DeleteApiConfig):len(c.CallOptions.DeleteApiConfig)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = c.client.DeleteApiConfig(ctx, req, settings.GRPC...)
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &DeleteApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, resp),
+	}, nil
+}
+
+// CreateApiOperation manages a long-running operation from CreateApi.
+type CreateApiOperation struct {
+	lro *longrunning.Operation
+}
+
+// CreateApiOperation returns a new CreateApiOperation from a given name.
+// The name must be that of a previously created CreateApiOperation, possibly from a different process.
+func (c *Client) CreateApiOperation(name string) *CreateApiOperation {
+	return &CreateApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *CreateApiOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Api, error) {
+	var resp apigatewaypb.Api
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *CreateApiOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Api, error) {
+	var resp apigatewaypb.Api
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *CreateApiOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *CreateApiOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *CreateApiOperation) Name() string {
+	return op.lro.Name()
+}
+
+// CreateApiConfigOperation manages a long-running operation from CreateApiConfig.
+type CreateApiConfigOperation struct {
+	lro *longrunning.Operation
+}
+
+// CreateApiConfigOperation returns a new CreateApiConfigOperation from a given name.
+// The name must be that of a previously created CreateApiConfigOperation, possibly from a different process.
+func (c *Client) CreateApiConfigOperation(name string) *CreateApiConfigOperation {
+	return &CreateApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *CreateApiConfigOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.ApiConfig, error) {
+	var resp apigatewaypb.ApiConfig
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *CreateApiConfigOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.ApiConfig, error) {
+	var resp apigatewaypb.ApiConfig
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *CreateApiConfigOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *CreateApiConfigOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *CreateApiConfigOperation) Name() string {
+	return op.lro.Name()
+}
+
+// CreateGatewayOperation manages a long-running operation from CreateGateway.
+type CreateGatewayOperation struct {
+	lro *longrunning.Operation
+}
+
+// CreateGatewayOperation returns a new CreateGatewayOperation from a given name.
+// The name must be that of a previously created CreateGatewayOperation, possibly from a different process.
+func (c *Client) CreateGatewayOperation(name string) *CreateGatewayOperation {
+	return &CreateGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *CreateGatewayOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Gateway, error) {
+	var resp apigatewaypb.Gateway
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *CreateGatewayOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Gateway, error) {
+	var resp apigatewaypb.Gateway
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *CreateGatewayOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *CreateGatewayOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *CreateGatewayOperation) Name() string {
+	return op.lro.Name()
+}
+
+// DeleteApiOperation manages a long-running operation from DeleteApi.
+type DeleteApiOperation struct {
+	lro *longrunning.Operation
+}
+
+// DeleteApiOperation returns a new DeleteApiOperation from a given name.
+// The name must be that of a previously created DeleteApiOperation, possibly from a different process.
+func (c *Client) DeleteApiOperation(name string) *DeleteApiOperation {
+	return &DeleteApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *DeleteApiOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *DeleteApiOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.Poll(ctx, nil, opts...)
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *DeleteApiOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *DeleteApiOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *DeleteApiOperation) Name() string {
+	return op.lro.Name()
+}
+
+// DeleteApiConfigOperation manages a long-running operation from DeleteApiConfig.
+type DeleteApiConfigOperation struct {
+	lro *longrunning.Operation
+}
+
+// DeleteApiConfigOperation returns a new DeleteApiConfigOperation from a given name.
+// The name must be that of a previously created DeleteApiConfigOperation, possibly from a different process.
+func (c *Client) DeleteApiConfigOperation(name string) *DeleteApiConfigOperation {
+	return &DeleteApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *DeleteApiConfigOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *DeleteApiConfigOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.Poll(ctx, nil, opts...)
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *DeleteApiConfigOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *DeleteApiConfigOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *DeleteApiConfigOperation) Name() string {
+	return op.lro.Name()
+}
+
+// DeleteGatewayOperation manages a long-running operation from DeleteGateway.
+type DeleteGatewayOperation struct {
+	lro *longrunning.Operation
+}
+
+// DeleteGatewayOperation returns a new DeleteGatewayOperation from a given name.
+// The name must be that of a previously created DeleteGatewayOperation, possibly from a different process.
+func (c *Client) DeleteGatewayOperation(name string) *DeleteGatewayOperation {
+	return &DeleteGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *DeleteGatewayOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *DeleteGatewayOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
+	return op.lro.Poll(ctx, nil, opts...)
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *DeleteGatewayOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *DeleteGatewayOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *DeleteGatewayOperation) Name() string {
+	return op.lro.Name()
+}
+
+// UpdateApiOperation manages a long-running operation from UpdateApi.
+type UpdateApiOperation struct {
+	lro *longrunning.Operation
+}
+
+// UpdateApiOperation returns a new UpdateApiOperation from a given name.
+// The name must be that of a previously created UpdateApiOperation, possibly from a different process.
+func (c *Client) UpdateApiOperation(name string) *UpdateApiOperation {
+	return &UpdateApiOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *UpdateApiOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Api, error) {
+	var resp apigatewaypb.Api
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *UpdateApiOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Api, error) {
+	var resp apigatewaypb.Api
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *UpdateApiOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *UpdateApiOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *UpdateApiOperation) Name() string {
+	return op.lro.Name()
+}
+
+// UpdateApiConfigOperation manages a long-running operation from UpdateApiConfig.
+type UpdateApiConfigOperation struct {
+	lro *longrunning.Operation
+}
+
+// UpdateApiConfigOperation returns a new UpdateApiConfigOperation from a given name.
+// The name must be that of a previously created UpdateApiConfigOperation, possibly from a different process.
+func (c *Client) UpdateApiConfigOperation(name string) *UpdateApiConfigOperation {
+	return &UpdateApiConfigOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *UpdateApiConfigOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.ApiConfig, error) {
+	var resp apigatewaypb.ApiConfig
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *UpdateApiConfigOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.ApiConfig, error) {
+	var resp apigatewaypb.ApiConfig
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *UpdateApiConfigOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *UpdateApiConfigOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *UpdateApiConfigOperation) Name() string {
+	return op.lro.Name()
+}
+
+// UpdateGatewayOperation manages a long-running operation from UpdateGateway.
+type UpdateGatewayOperation struct {
+	lro *longrunning.Operation
+}
+
+// UpdateGatewayOperation returns a new UpdateGatewayOperation from a given name.
+// The name must be that of a previously created UpdateGatewayOperation, possibly from a different process.
+func (c *Client) UpdateGatewayOperation(name string) *UpdateGatewayOperation {
+	return &UpdateGatewayOperation{
+		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
+	}
+}
+
+// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
+//
+// See documentation of Poll for error-handling information.
+func (op *UpdateGatewayOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Gateway, error) {
+	var resp apigatewaypb.Gateway
+	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
+		return nil, err
+	}
+	return &resp, nil
+}
+
+// Poll fetches the latest state of the long-running operation.
+//
+// Poll also fetches the latest metadata, which can be retrieved by Metadata.
+//
+// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
+// the operation has completed with failure, the error is returned and op.Done will return true.
+// If Poll succeeds and the operation has completed successfully,
+// op.Done will return true, and the response of the operation is returned.
+// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
+func (op *UpdateGatewayOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*apigatewaypb.Gateway, error) {
+	var resp apigatewaypb.Gateway
+	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
+		return nil, err
+	}
+	if !op.Done() {
+		return nil, nil
+	}
+	return &resp, nil
+}
+
+// Metadata returns metadata associated with the long-running operation.
+// Metadata itself does not contact the server, but Poll does.
+// To get the latest metadata, call this method after a successful call to Poll.
+// If the metadata is not available, the returned metadata and error are both nil.
+func (op *UpdateGatewayOperation) Metadata() (*apigatewaypb.OperationMetadata, error) {
+	var meta apigatewaypb.OperationMetadata
+	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
+		return nil, nil
+	} else if err != nil {
+		return nil, err
+	}
+	return &meta, nil
+}
+
+// Done reports whether the long-running operation has completed.
+func (op *UpdateGatewayOperation) Done() bool {
+	return op.lro.Done()
+}
+
+// Name returns the name of the long-running operation.
+// The name is assigned by the server and is unique within the service from which the operation is created.
+func (op *UpdateGatewayOperation) Name() string {
+	return op.lro.Name()
+}
+
+// ApiConfigIterator manages a stream of *apigatewaypb.ApiConfig.
+type ApiConfigIterator struct {
+	items    []*apigatewaypb.ApiConfig
+	pageInfo *iterator.PageInfo
+	nextFunc func() error
+
+	// Response is the raw response for the current page.
+	// It must be cast to the RPC response type.
+	// Calling Next() or InternalFetch() updates this value.
+	Response interface{}
+
+	// InternalFetch is for use by the Google Cloud Libraries only.
+	// It is not part of the stable interface of this package.
+	//
+	// InternalFetch returns results from a single call to the underlying RPC.
+	// The number of results is no greater than pageSize.
+	// If there are no more results, nextPageToken is empty and err is nil.
+	InternalFetch func(pageSize int, pageToken string) (results []*apigatewaypb.ApiConfig, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
+func (it *ApiConfigIterator) PageInfo() *iterator.PageInfo {
+	return it.pageInfo
+}
+
+// Next returns the next result. Its second return value is iterator.Done if there are no more
+// results. Once Next returns Done, all subsequent calls will return Done.
+func (it *ApiConfigIterator) Next() (*apigatewaypb.ApiConfig, error) {
+	var item *apigatewaypb.ApiConfig
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *ApiConfigIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *ApiConfigIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
+
+// ApiIterator manages a stream of *apigatewaypb.Api.
+type ApiIterator struct {
+	items    []*apigatewaypb.Api
+	pageInfo *iterator.PageInfo
+	nextFunc func() error
+
+	// Response is the raw response for the current page.
+	// It must be cast to the RPC response type.
+	// Calling Next() or InternalFetch() updates this value.
+	Response interface{}
+
+	// InternalFetch is for use by the Google Cloud Libraries only.
+	// It is not part of the stable interface of this package.
+	//
+	// InternalFetch returns results from a single call to the underlying RPC.
+	// The number of results is no greater than pageSize.
+	// If there are no more results, nextPageToken is empty and err is nil.
+	InternalFetch func(pageSize int, pageToken string) (results []*apigatewaypb.Api, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
+func (it *ApiIterator) PageInfo() *iterator.PageInfo {
+	return it.pageInfo
+}
+
+// Next returns the next result. Its second return value is iterator.Done if there are no more
+// results. Once Next returns Done, all subsequent calls will return Done.
+func (it *ApiIterator) Next() (*apigatewaypb.Api, error) {
+	var item *apigatewaypb.Api
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *ApiIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *ApiIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
+
+// GatewayIterator manages a stream of *apigatewaypb.Gateway.
+type GatewayIterator struct {
+	items    []*apigatewaypb.Gateway
+	pageInfo *iterator.PageInfo
+	nextFunc func() error
+
+	// Response is the raw response for the current page.
+	// It must be cast to the RPC response type.
+	// Calling Next() or InternalFetch() updates this value.
+	Response interface{}
+
+	// InternalFetch is for use by the Google Cloud Libraries only.
+	// It is not part of the stable interface of this package.
+	//
+	// InternalFetch returns results from a single call to the underlying RPC.
+	// The number of results is no greater than pageSize.
+	// If there are no more results, nextPageToken is empty and err is nil.
+	InternalFetch func(pageSize int, pageToken string) (results []*apigatewaypb.Gateway, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
+func (it *GatewayIterator) PageInfo() *iterator.PageInfo {
+	return it.pageInfo
+}
+
+// Next returns the next result. Its second return value is iterator.Done if there are no more
+// results. Once Next returns Done, all subsequent calls will return Done.
+func (it *GatewayIterator) Next() (*apigatewaypb.Gateway, error) {
+	var item *apigatewaypb.Gateway
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *GatewayIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *GatewayIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
diff --git a/apigateway/apiv1/api_gateway_client_example_test.go b/apigateway/apiv1/api_gateway_client_example_test.go
new file mode 100644
index 0000000..6c1d060
--- /dev/null
+++ b/apigateway/apiv1/api_gateway_client_example_test.go
@@ -0,0 +1,395 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+package apigateway_test
+
+import (
+	"context"
+
+	apigateway "cloud.google.com/go/apigateway/apiv1"
+	"google.golang.org/api/iterator"
+	apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+)
+
+func ExampleNewClient() {
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleClient_ListGateways() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+	// import "google.golang.org/api/iterator"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.ListGatewaysRequest{
+		// TODO: Fill request struct fields.
+	}
+	it := c.ListGateways(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
+
+func ExampleClient_GetGateway() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.GetGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetGateway(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_CreateGateway() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.CreateGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.CreateGateway(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_UpdateGateway() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.UpdateGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.UpdateGateway(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_DeleteGateway() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.DeleteGatewayRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.DeleteGateway(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	err = op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+func ExampleClient_ListApis() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+	// import "google.golang.org/api/iterator"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.ListApisRequest{
+		// TODO: Fill request struct fields.
+	}
+	it := c.ListApis(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
+
+func ExampleClient_GetApi() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.GetApiRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetApi(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_CreateApi() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.CreateApiRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.CreateApi(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_UpdateApi() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.UpdateApiRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.UpdateApi(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_DeleteApi() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.DeleteApiRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.DeleteApi(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	err = op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+func ExampleClient_ListApiConfigs() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+	// import "google.golang.org/api/iterator"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.ListApiConfigsRequest{
+		// TODO: Fill request struct fields.
+	}
+	it := c.ListApiConfigs(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
+
+func ExampleClient_GetApiConfig() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.GetApiConfigRequest{
+		// TODO: Fill request struct fields.
+	}
+	resp, err := c.GetApiConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_CreateApiConfig() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.CreateApiConfigRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.CreateApiConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_UpdateApiConfig() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.UpdateApiConfigRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.UpdateApiConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	resp, err := op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_DeleteApiConfig() {
+	// import apigatewaypb "google.golang.org/genproto/googleapis/cloud/apigateway/v1"
+
+	ctx := context.Background()
+	c, err := apigateway.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	req := &apigatewaypb.DeleteApiConfigRequest{
+		// TODO: Fill request struct fields.
+	}
+	op, err := c.DeleteApiConfig(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+
+	err = op.Wait(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
diff --git a/apigateway/apiv1/doc.go b/apigateway/apiv1/doc.go
new file mode 100644
index 0000000..be76bd3
--- /dev/null
+++ b/apigateway/apiv1/doc.go
@@ -0,0 +1,114 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
+
+// Package apigateway is an auto-generated package for the
+// API Gateway API.
+//
+// Use of Context
+//
+// The ctx passed to NewClient is used for authentication requests and
+// for creating the underlying connection, but is not used for subsequent calls.
+// Individual methods on the client use the ctx given to them.
+//
+// To close the open connection, use the Close() method.
+//
+// For information about setting deadlines, reusing contexts, and more
+// please visit pkg.go.dev/cloud.google.com/go.
+package apigateway // import "cloud.google.com/go/apigateway/apiv1"
+
+import (
+	"context"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+	"unicode"
+
+	"google.golang.org/api/option"
+	"google.golang.org/grpc/metadata"
+)
+
+// For more information on implementing a client constructor hook, see
+// https://github.com/googleapis/google-cloud-go/wiki/Customizing-constructors.
+type clientHookParams struct{}
+type clientHook func(context.Context, clientHookParams) ([]option.ClientOption, error)
+
+const versionClient = "20210223"
+
+func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
+	out, _ := metadata.FromOutgoingContext(ctx)
+	out = out.Copy()
+	for _, md := range mds {
+		for k, v := range md {
+			out[k] = append(out[k], v...)
+		}
+	}
+	return metadata.NewOutgoingContext(ctx, out)
+}
+
+func checkDisableDeadlines() (bool, error) {
+	raw, ok := os.LookupEnv("GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE")
+	if !ok {
+		return false, nil
+	}
+
+	b, err := strconv.ParseBool(raw)
+	return b, err
+}
+
+// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
+func DefaultAuthScopes() []string {
+	return []string{
+		"https://www.googleapis.com/auth/cloud-platform",
+	}
+}
+
+// versionGo returns the Go runtime version. The returned string
+// has no whitespace, suitable for reporting in header.
+func versionGo() string {
+	const develPrefix = "devel +"
+
+	s := runtime.Version()
+	if strings.HasPrefix(s, develPrefix) {
+		s = s[len(develPrefix):]
+		if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 {
+			s = s[:p]
+		}
+		return s
+	}
+
+	notSemverRune := func(r rune) bool {
+		return !strings.ContainsRune("0123456789.", r)
+	}
+
+	if strings.HasPrefix(s, "go1") {
+		s = s[2:]
+		var prerelease string
+		if p := strings.IndexFunc(s, notSemverRune); p >= 0 {
+			s, prerelease = s[:p], s[p:]
+		}
+		if strings.HasSuffix(s, ".") {
+			s += "0"
+		} else if strings.Count(s, ".") < 2 {
+			s += ".0"
+		}
+		if prerelease != "" {
+			s += "-" + prerelease
+		}
+		return s
+	}
+	return "UNKNOWN"
+}
diff --git a/apigateway/apiv1/gapic_metadata.json b/apigateway/apiv1/gapic_metadata.json
new file mode 100644
index 0000000..80e7cec
--- /dev/null
+++ b/apigateway/apiv1/gapic_metadata.json
@@ -0,0 +1,93 @@
+{
+  "schema": "1.0",
+  "comment": "This file maps proto services/RPCs to the corresponding library clients/methods.",
+  "language": "go",
+  "protoPackage": "google.cloud.apigateway.v1",
+  "libraryPackage": "cloud.google.com/go/apigateway/apiv1",
+  "services": {
+    "ApiGatewayService": {
+      "clients": {
+        "grpc": {
+          "libraryClient": "Client",
+          "rpcs": {
+            "CreateApi": {
+              "methods": [
+                "CreateApi"
+              ]
+            },
+            "CreateApiConfig": {
+              "methods": [
+                "CreateApiConfig"
+              ]
+            },
+            "CreateGateway": {
+              "methods": [
+                "CreateGateway"
+              ]
+            },
+            "DeleteApi": {
+              "methods": [
+                "DeleteApi"
+              ]
+            },
+            "DeleteApiConfig": {
+              "methods": [
+                "DeleteApiConfig"
+              ]
+            },
+            "DeleteGateway": {
+              "methods": [
+                "DeleteGateway"
+              ]
+            },
+            "GetApi": {
+              "methods": [
+                "GetApi"
+              ]
+            },
+            "GetApiConfig": {
+              "methods": [
+                "GetApiConfig"
+              ]
+            },
+            "GetGateway": {
+              "methods": [
+                "GetGateway"
+              ]
+            },
+            "ListApiConfigs": {
+              "methods": [
+                "ListApiConfigs"
+              ]
+            },
+            "ListApis": {
+              "methods": [
+                "ListApis"
+              ]
+            },
+            "ListGateways": {
+              "methods": [
+                "ListGateways"
+              ]
+            },
+            "UpdateApi": {
+              "methods": [
+                "UpdateApi"
+              ]
+            },
+            "UpdateApiConfig": {
+              "methods": [
+                "UpdateApiConfig"
+              ]
+            },
+            "UpdateGateway": {
+              "methods": [
+                "UpdateGateway"
+              ]
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/internal/.repo-metadata-full.json b/internal/.repo-metadata-full.json
index 6e14434..c952770 100644
--- a/internal/.repo-metadata-full.json
+++ b/internal/.repo-metadata-full.json
@@ -23,6 +23,14 @@
     "docs_url": "https://pkg.go.dev/cloud.google.com/go/analytics/data/apiv1alpha",
     "release_level": "alpha"
   },
+  "cloud.google.com/go/apigateway/apiv1": {
+    "distribution_name": "cloud.google.com/go/apigateway/apiv1",
+    "description": "API Gateway API",
+    "language": "Go",
+    "client_library_type": "generated",
+    "docs_url": "https://pkg.go.dev/cloud.google.com/go/apigateway/apiv1",
+    "release_level": "beta"
+  },
   "cloud.google.com/go/appengine/apiv1": {
     "distribution_name": "cloud.google.com/go/appengine/apiv1",
     "description": "App Engine Audit Data",
diff --git a/internal/gapicgen/generator/config.go b/internal/gapicgen/generator/config.go
index ecfffa5..5084dbb 100644
--- a/internal/gapicgen/generator/config.go
+++ b/internal/gapicgen/generator/config.go
@@ -1008,6 +1008,15 @@
 		apiServiceConfigPath:  "google/cloud/gkehub/v1beta1/gkehub_v1beta1.yaml",
 		releaseLevel:          "beta",
 	},
+	{
+		inputDirectoryPath:    "google/cloud/apigateway/v1",
+		pkg:                   "apigateway",
+		importPath:            "cloud.google.com/go/apigateway/apiv1",
+		gRPCServiceConfigPath: "google/cloud/apigateway/v1/apigateway_grpc_service_config.json",
+		apiServiceConfigPath:  "google/cloud/apigateway/v1/apigateway_v1.yaml",
+		// GA after 2021/03/23
+		releaseLevel: "beta",
+	},
 
 	// Non-Cloud APIs
 	{
