feat(google/cloud/apptopology/v1): onboard a new library (#20434)
diff --git a/.release-please-bulk-manifest.json b/.release-please-bulk-manifest.json
index 80c1dd1..5a5a31d 100644
--- a/.release-please-bulk-manifest.json
+++ b/.release-please-bulk-manifest.json
@@ -18,6 +18,7 @@
   "apphub": "1.1.0",
   "appoptimize": "0.5.0",
   "apps": "1.1.0",
+  "apptopology": "0.0.0",
   "area120": "0.15.0",
   "artifactregistry": "1.26.0",
   "asset": "1.28.0",
diff --git a/apptopology/README.md b/apptopology/README.md
new file mode 100644
index 0000000..361e970
--- /dev/null
+++ b/apptopology/README.md
@@ -0,0 +1,55 @@
+# App Topology API
+
+[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/apptopology.svg)](https://pkg.go.dev/cloud.google.com/go/apptopology)
+
+Go Client Library for App Topology API.
+
+## Install
+
+```bash
+go get cloud.google.com/go/apptopology
+```
+
+## Stability
+
+The stability of this module is indicated by SemVer.
+
+However, a `v1+` module may have breaking changes in two scenarios:
+
+* Packages with `alpha` or `beta` in the import path
+* The GoDoc has an explicit stability disclaimer (for example, for an experimental feature).
+
+### Which package to use?
+
+Generated client library surfaces can be found in packages whose import path
+ends in `.../apivXXX`. The `XXX` could be something like `1` or `2` in the case
+of a stable service backend or may be like `1beta2` or `2beta` in the case of a
+more experimental service backend. Because of this fact, a given module can have
+multiple clients for different service backends. In these cases it is generally
+recommended to use clients with stable service backends, with import suffixes like
+`apiv1`, unless you need to use features that are only present in a beta backend
+or there is not yet a stable backend available.
+
+## Google Cloud Samples
+
+To browse ready to use code samples check [Google Cloud Samples](https://cloud.google.com/docs/samples?l=go).
+
+## Go Version Support
+
+See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported)
+section in the root directory's README.
+
+## Authorization
+
+See the [Authorization](https://github.com/googleapis/google-cloud-go#authorization)
+section in the root directory's README.
+
+## Contributing
+
+Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md)
+document for details.
+
+Please note that this project is released with a Contributor Code of Conduct.
+By participating in this project you agree to abide by its terms. See
+[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct)
+for more information.
diff --git a/apptopology/apiv1/.repo-metadata.json b/apptopology/apiv1/.repo-metadata.json
new file mode 100644
index 0000000..050465f
--- /dev/null
+++ b/apptopology/apiv1/.repo-metadata.json
@@ -0,0 +1,10 @@
+{
+    "api_shortname": "apptopology",
+    "client_documentation": "https://cloud.google.com/go/docs/reference/cloud.google.com/go/apptopology/latest/apiv1",
+    "client_library_type": "generated",
+    "description": "App Topology API",
+    "distribution_name": "cloud.google.com/go/apptopology/apiv1",
+    "language": "go",
+    "library_type": "GAPIC_AUTO",
+    "release_level": "preview"
+}
\ No newline at end of file
diff --git a/apptopology/apiv1/app_topology_client.go b/apptopology/apiv1/app_topology_client.go
new file mode 100644
index 0000000..f2bffcd
--- /dev/null
+++ b/apptopology/apiv1/app_topology_client.go
@@ -0,0 +1,1455 @@
+// Copyright 2026 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 apptopology
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"log/slog"
+	"math"
+	"net/http"
+	"net/url"
+	"time"
+
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+	gax "github.com/googleapis/gax-go/v2"
+	"github.com/googleapis/gax-go/v2/callctx"
+	"google.golang.org/api/iterator"
+	"google.golang.org/api/option"
+	"google.golang.org/api/option/internaloption"
+	gtransport "google.golang.org/api/transport/grpc"
+	httptransport "google.golang.org/api/transport/http"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
+)
+
+var newClientHook clientHook
+
+// CallOptions contains the retry settings for each method of Client.
+type CallOptions struct {
+	GenerateDiscoveredResourcesTopology []gax.CallOption
+	GetSchema                           []gax.CallOption
+	GetDomain                           []gax.CallOption
+	ListDomains                         []gax.CallOption
+	GetLocation                         []gax.CallOption
+	ListLocations                       []gax.CallOption
+	CancelOperation                     []gax.CallOption
+	DeleteOperation                     []gax.CallOption
+	GetOperation                        []gax.CallOption
+	ListOperations                      []gax.CallOption
+}
+
+func defaultGRPCClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("apptopology.googleapis.com:443"),
+		internaloption.WithDefaultEndpointTemplate("apptopology.UNIVERSE_DOMAIN:443"),
+		internaloption.WithDefaultMTLSEndpoint("apptopology.mtls.googleapis.com:443"),
+		internaloption.WithDefaultUniverseDomain("googleapis.com"),
+		internaloption.WithDefaultAudience("https://apptopology.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+		internaloption.EnableJwtWithScope(),
+		internaloption.EnableNewAuthLibrary(),
+		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
+			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
+	}
+}
+
+func defaultCallOptions() *CallOptions {
+	return &CallOptions{
+		GenerateDiscoveredResourcesTopology: []gax.CallOption{
+			gax.WithTimeout(300000 * time.Millisecond),
+		},
+		GetSchema: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				})
+			}),
+		},
+		GetDomain: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				})
+			}),
+		},
+		ListDomains: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnCodes([]codes.Code{
+					codes.Unavailable,
+				}, gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				})
+			}),
+		},
+		GetLocation:     []gax.CallOption{},
+		ListLocations:   []gax.CallOption{},
+		CancelOperation: []gax.CallOption{},
+		DeleteOperation: []gax.CallOption{},
+		GetOperation:    []gax.CallOption{},
+		ListOperations:  []gax.CallOption{},
+	}
+}
+
+func defaultRESTCallOptions() *CallOptions {
+	return &CallOptions{
+		GenerateDiscoveredResourcesTopology: []gax.CallOption{
+			gax.WithTimeout(300000 * time.Millisecond),
+		},
+		GetSchema: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnHTTPCodes(gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				},
+					http.StatusServiceUnavailable)
+			}),
+		},
+		GetDomain: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnHTTPCodes(gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				},
+					http.StatusServiceUnavailable)
+			}),
+		},
+		ListDomains: []gax.CallOption{
+			gax.WithTimeout(60000 * time.Millisecond),
+			gax.WithRetry(func() gax.Retryer {
+				return gax.OnHTTPCodes(gax.Backoff{
+					Initial:    1000 * time.Millisecond,
+					Max:        10000 * time.Millisecond,
+					Multiplier: 1.30,
+				},
+					http.StatusServiceUnavailable)
+			}),
+		},
+		GetLocation:     []gax.CallOption{},
+		ListLocations:   []gax.CallOption{},
+		CancelOperation: []gax.CallOption{},
+		DeleteOperation: []gax.CallOption{},
+		GetOperation:    []gax.CallOption{},
+		ListOperations:  []gax.CallOption{},
+	}
+}
+
+// internalClient is an interface that defines the methods available from App Topology API.
+type internalClient interface {
+	Close() error
+	setGoogleClientInfo(...string)
+	Connection() *grpc.ClientConn
+	GenerateDiscoveredResourcesTopology(context.Context, *apptopologypb.GenerateDiscoveredResourcesTopologyRequest, ...gax.CallOption) (*apptopologypb.GenerateDiscoveredResourcesTopologyResponse, error)
+	GetSchema(context.Context, *apptopologypb.GetSchemaRequest, ...gax.CallOption) (*apptopologypb.Schema, error)
+	GetDomain(context.Context, *apptopologypb.GetDomainRequest, ...gax.CallOption) (*apptopologypb.Domain, error)
+	ListDomains(context.Context, *apptopologypb.ListDomainsRequest, ...gax.CallOption) *DomainIterator
+	GetLocation(context.Context, *locationpb.GetLocationRequest, ...gax.CallOption) (*locationpb.Location, error)
+	ListLocations(context.Context, *locationpb.ListLocationsRequest, ...gax.CallOption) *LocationIterator
+	CancelOperation(context.Context, *longrunningpb.CancelOperationRequest, ...gax.CallOption) error
+	DeleteOperation(context.Context, *longrunningpb.DeleteOperationRequest, ...gax.CallOption) error
+	GetOperation(context.Context, *longrunningpb.GetOperationRequest, ...gax.CallOption) (*longrunningpb.Operation, error)
+	ListOperations(context.Context, *longrunningpb.ListOperationsRequest, ...gax.CallOption) *OperationIterator
+}
+
+// Client is a client for interacting with App Topology API.
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+//
+// Service describing handlers for resources
+type Client struct {
+	// The internal transport-dependent client.
+	internalClient internalClient
+
+	// The call options for this service.
+	CallOptions *CallOptions
+}
+
+// Wrapper methods routed to the internal client.
+
+// Close closes the connection to the API service. **Always** call Close() when
+// the client is no longer required.
+func (c *Client) Close() error {
+	return c.internalClient.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) {
+	c.internalClient.setGoogleClientInfo(keyval...)
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated: Connections are now pooled so this method does not always
+// return the same resource.
+func (c *Client) Connection() *grpc.ClientConn {
+	return c.internalClient.Connection()
+}
+
+// GenerateDiscoveredResourcesTopology generate the topology for all resources in the given project. If the
+// project represents an
+// app
+// boundary (at https://cloud.google.com/app-hub/docs/reference/rest/v1/Boundary),
+// the topology is generated for all resources in the boundary.
+func (c *Client) GenerateDiscoveredResourcesTopology(ctx context.Context, req *apptopologypb.GenerateDiscoveredResourcesTopologyRequest, opts ...gax.CallOption) (*apptopologypb.GenerateDiscoveredResourcesTopologyResponse, error) {
+	return c.internalClient.GenerateDiscoveredResourcesTopology(ctx, req, opts...)
+}
+
+// GetSchema retrieves the schema for the specified topology domain. The schema
+// defines the NodeTypes and EdgeTypes that are supported in
+// GenerateDiscoveredResourcesTopology requests and responses for a given
+// domain.
+func (c *Client) GetSchema(ctx context.Context, req *apptopologypb.GetSchemaRequest, opts ...gax.CallOption) (*apptopologypb.Schema, error) {
+	return c.internalClient.GetSchema(ctx, req, opts...)
+}
+
+// GetDomain retrieves the specified topology domain.
+func (c *Client) GetDomain(ctx context.Context, req *apptopologypb.GetDomainRequest, opts ...gax.CallOption) (*apptopologypb.Domain, error) {
+	return c.internalClient.GetDomain(ctx, req, opts...)
+}
+
+// ListDomains lists the topology domains available in a specific location.
+// Only global location is supported.
+func (c *Client) ListDomains(ctx context.Context, req *apptopologypb.ListDomainsRequest, opts ...gax.CallOption) *DomainIterator {
+	return c.internalClient.ListDomains(ctx, req, opts...)
+}
+
+// GetLocation gets information about a location.
+func (c *Client) GetLocation(ctx context.Context, req *locationpb.GetLocationRequest, opts ...gax.CallOption) (*locationpb.Location, error) {
+	return c.internalClient.GetLocation(ctx, req, opts...)
+}
+
+// ListLocations lists information about the supported locations for this service.
+//
+// This method lists locations based on the resource scope provided in
+// the [ListLocationsRequest.name (at http://ListLocationsRequest.name)][google.cloud.location.ListLocationsRequest.name (at http://google.cloud.location.ListLocationsRequest.name)] field: *
+// Global locations: If name is empty, the method lists the
+// public locations available to all projects. * Project-specific
+// locations: If name follows the format
+// projects/{project}, the method lists locations visible to that
+// specific project. This includes public, private, or other
+// project-specific locations enabled for the project.
+//
+// For gRPC and client library implementations, the resource name is
+// passed as the name field. For direct service calls, the resource
+// name is
+// incorporated into the request path based on the specific service
+// implementation and version.
+func (c *Client) ListLocations(ctx context.Context, req *locationpb.ListLocationsRequest, opts ...gax.CallOption) *LocationIterator {
+	return c.internalClient.ListLocations(ctx, req, opts...)
+}
+
+// CancelOperation is a utility method from google.longrunning.Operations.
+func (c *Client) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest, opts ...gax.CallOption) error {
+	return c.internalClient.CancelOperation(ctx, req, opts...)
+}
+
+// DeleteOperation is a utility method from google.longrunning.Operations.
+func (c *Client) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest, opts ...gax.CallOption) error {
+	return c.internalClient.DeleteOperation(ctx, req, opts...)
+}
+
+// GetOperation is a utility method from google.longrunning.Operations.
+func (c *Client) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) {
+	return c.internalClient.GetOperation(ctx, req, opts...)
+}
+
+// ListOperations is a utility method from google.longrunning.Operations.
+func (c *Client) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest, opts ...gax.CallOption) *OperationIterator {
+	return c.internalClient.ListOperations(ctx, req, opts...)
+}
+
+// gRPCClient is a client for interacting with App Topology API over gRPC transport.
+//
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type gRPCClient struct {
+	// Connection pool of gRPC connections to the service.
+	connPool gtransport.ConnPool
+
+	// Points back to the CallOptions field of the containing Client
+	CallOptions **CallOptions
+
+	// The gRPC API client.
+	client apptopologypb.AppTopologyClient
+
+	operationsClient longrunningpb.OperationsClient
+
+	locationsClient locationpb.LocationsClient
+
+	// The x-goog-* metadata to be sent with each request.
+	xGoogHeaders []string
+
+	logger *slog.Logger
+}
+
+// NewClient creates a new app topology client based on gRPC.
+// The returned client must be Closed when it is done being used to clean up its underlying connections.
+//
+// Service describing handlers for resources
+func NewClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
+	clientOpts := defaultGRPCClientOptions()
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		clientOpts = append(clientOpts, internaloption.WithTelemetryAttributes(map[string]string{
+			"gcp.client.service":  "apptopology",
+			"gcp.client.version":  getVersionClient(),
+			"gcp.client.repo":     "googleapis/google-cloud-go",
+			"gcp.client.artifact": "cloud.google.com/go/apptopology/apiv1",
+			"gcp.client.language": "go",
+			"url.domain":          "apptopology.googleapis.com",
+		}))
+	}
+	if newClientHook != nil {
+		hookOpts, err := newClientHook(ctx, clientHookParams{})
+		if err != nil {
+			return nil, err
+		}
+		clientOpts = append(clientOpts, hookOpts...)
+	}
+
+	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
+	if err != nil {
+		return nil, err
+	}
+	client := Client{CallOptions: defaultCallOptions()}
+
+	c := &gRPCClient{
+		connPool:         connPool,
+		client:           apptopologypb.NewAppTopologyClient(connPool),
+		CallOptions:      &client.CallOptions,
+		logger:           internaloption.GetLogger(opts),
+		operationsClient: longrunningpb.NewOperationsClient(connPool),
+		locationsClient:  locationpb.NewLocationsClient(connPool),
+	}
+	c.setGoogleClientInfo()
+	if gax.IsFeatureEnabled("METRICS") {
+		metrics := gax.NewClientMetrics(
+			gax.WithTelemetryLogger(c.logger),
+			gax.WithTelemetryAttributes(map[string]string{
+				gax.ClientService:  "apptopology",
+				gax.ClientVersion:  getVersionClient(),
+				gax.ClientArtifact: "cloud.google.com/go/apptopology/apiv1",
+				gax.RPCSystem:      "grpc",
+				gax.URLDomain:      "apptopology.googleapis.com",
+			}),
+		)
+
+		client.CallOptions.GenerateDiscoveredResourcesTopology = append(client.CallOptions.GenerateDiscoveredResourcesTopology, gax.WithClientMetrics(metrics))
+		client.CallOptions.GetSchema = append(client.CallOptions.GetSchema, gax.WithClientMetrics(metrics))
+		client.CallOptions.GetDomain = append(client.CallOptions.GetDomain, gax.WithClientMetrics(metrics))
+		client.CallOptions.ListDomains = append(client.CallOptions.ListDomains, gax.WithClientMetrics(metrics))
+		client.CallOptions.GetLocation = append(client.CallOptions.GetLocation, gax.WithClientMetrics(metrics))
+		client.CallOptions.ListLocations = append(client.CallOptions.ListLocations, gax.WithClientMetrics(metrics))
+		client.CallOptions.CancelOperation = append(client.CallOptions.CancelOperation, gax.WithClientMetrics(metrics))
+		client.CallOptions.DeleteOperation = append(client.CallOptions.DeleteOperation, gax.WithClientMetrics(metrics))
+		client.CallOptions.GetOperation = append(client.CallOptions.GetOperation, gax.WithClientMetrics(metrics))
+		client.CallOptions.ListOperations = append(client.CallOptions.ListOperations, gax.WithClientMetrics(metrics))
+	}
+
+	client.internalClient = c
+
+	return &client, nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated: Connections are now pooled so this method does not always
+// return the same resource.
+func (c *gRPCClient) Connection() *grpc.ClientConn {
+	return c.connPool.Conn()
+}
+
+// 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 *gRPCClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
+	kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "grpc", grpc.Version, "pb", protoVersion)
+	c.xGoogHeaders = []string{
+		"x-goog-api-client", gax.XGoogHeader(kv...),
+	}
+}
+
+// Close closes the connection to the API service. **Always** call Close() when
+// the client is no longer required.
+func (c *gRPCClient) Close() error {
+	return c.connPool.Close()
+}
+
+// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
+type restClient struct {
+	// The http endpoint to connect to.
+	endpoint string
+
+	// The http client.
+	httpClient *http.Client
+
+	// The x-goog-* headers to be sent with each request.
+	xGoogHeaders []string
+
+	// Points back to the CallOptions field of the containing Client
+	CallOptions **CallOptions
+
+	logger *slog.Logger
+}
+
+// NewRESTClient creates a new app topology rest client.
+//
+// Service describing handlers for resources
+func NewRESTClient(ctx context.Context, opts ...option.ClientOption) (*Client, error) {
+	clientOpts := append(defaultRESTClientOptions(), opts...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		clientOpts = append(clientOpts, internaloption.WithTelemetryAttributes(map[string]string{
+			"gcp.client.service":  "apptopology",
+			"gcp.client.version":  getVersionClient(),
+			"gcp.client.repo":     "googleapis/google-cloud-go",
+			"gcp.client.artifact": "cloud.google.com/go/apptopology/apiv1",
+			"gcp.client.language": "go",
+			"url.domain":          "apptopology.googleapis.com",
+		}))
+	}
+	httpClient, endpoint, err := httptransport.NewClient(ctx, clientOpts...)
+	if err != nil {
+		return nil, err
+	}
+
+	callOpts := defaultRESTCallOptions()
+	c := &restClient{
+		endpoint:    endpoint,
+		httpClient:  httpClient,
+		CallOptions: &callOpts,
+		logger:      internaloption.GetLogger(opts),
+	}
+	c.setGoogleClientInfo()
+
+	if gax.IsFeatureEnabled("METRICS") {
+		metrics := gax.NewClientMetrics(
+			gax.WithTelemetryLogger(c.logger),
+			gax.WithTelemetryAttributes(map[string]string{
+				gax.ClientService:  "apptopology",
+				gax.ClientVersion:  getVersionClient(),
+				gax.ClientArtifact: "cloud.google.com/go/apptopology/apiv1",
+				gax.RPCSystem:      "http",
+				gax.URLDomain:      "apptopology.googleapis.com",
+			}),
+		)
+
+		callOpts.GenerateDiscoveredResourcesTopology = append(callOpts.GenerateDiscoveredResourcesTopology, gax.WithClientMetrics(metrics))
+		callOpts.GetSchema = append(callOpts.GetSchema, gax.WithClientMetrics(metrics))
+		callOpts.GetDomain = append(callOpts.GetDomain, gax.WithClientMetrics(metrics))
+		callOpts.ListDomains = append(callOpts.ListDomains, gax.WithClientMetrics(metrics))
+		callOpts.GetLocation = append(callOpts.GetLocation, gax.WithClientMetrics(metrics))
+		callOpts.ListLocations = append(callOpts.ListLocations, gax.WithClientMetrics(metrics))
+		callOpts.CancelOperation = append(callOpts.CancelOperation, gax.WithClientMetrics(metrics))
+		callOpts.DeleteOperation = append(callOpts.DeleteOperation, gax.WithClientMetrics(metrics))
+		callOpts.GetOperation = append(callOpts.GetOperation, gax.WithClientMetrics(metrics))
+		callOpts.ListOperations = append(callOpts.ListOperations, gax.WithClientMetrics(metrics))
+	}
+
+	return &Client{internalClient: c, CallOptions: callOpts}, nil
+}
+
+func defaultRESTClientOptions() []option.ClientOption {
+	return []option.ClientOption{
+		internaloption.WithDefaultEndpoint("https://apptopology.googleapis.com"),
+		internaloption.WithDefaultEndpointTemplate("https://apptopology.UNIVERSE_DOMAIN"),
+		internaloption.WithDefaultMTLSEndpoint("https://apptopology.mtls.googleapis.com"),
+		internaloption.WithDefaultUniverseDomain("googleapis.com"),
+		internaloption.WithDefaultAudience("https://apptopology.googleapis.com/"),
+		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
+		internaloption.EnableNewAuthLibrary(),
+	}
+}
+
+// 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 *restClient) setGoogleClientInfo(keyval ...string) {
+	kv := append([]string{"gl-go", gax.GoVersion}, keyval...)
+	kv = append(kv, "gapic", getVersionClient(), "gax", gax.Version, "rest", "UNKNOWN", "pb", protoVersion)
+	c.xGoogHeaders = []string{
+		"x-goog-api-client", gax.XGoogHeader(kv...),
+	}
+}
+
+// Close closes the connection to the API service. **Always** call Close() when
+// the client is no longer required.
+func (c *restClient) Close() error {
+	// Replace httpClient with nil to force cleanup.
+	c.httpClient = nil
+	return nil
+}
+
+// Connection returns a connection to the API service.
+//
+// Deprecated: This method always returns nil.
+func (c *restClient) Connection() *grpc.ClientConn {
+	return nil
+}
+func (c *gRPCClient) GenerateDiscoveredResourcesTopology(ctx context.Context, req *apptopologypb.GenerateDiscoveredResourcesTopologyRequest, opts ...gax.CallOption) (*apptopologypb.GenerateDiscoveredResourcesTopologyResponse, error) {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GenerateDiscoveredResourcesTopology")
+	}
+	opts = append((*c.CallOptions).GenerateDiscoveredResourcesTopology[0:len((*c.CallOptions).GenerateDiscoveredResourcesTopology):len((*c.CallOptions).GenerateDiscoveredResourcesTopology)], opts...)
+	var resp *apptopologypb.GenerateDiscoveredResourcesTopologyResponse
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = executeRPC(ctx, c.client.GenerateDiscoveredResourcesTopology, req, settings.GRPC, c.logger, "GenerateDiscoveredResourcesTopology")
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func (c *gRPCClient) GetSchema(ctx context.Context, req *apptopologypb.GetSchemaRequest, opts ...gax.CallOption) (*apptopologypb.Schema, error) {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GetSchema")
+	}
+	opts = append((*c.CallOptions).GetSchema[0:len((*c.CallOptions).GetSchema):len((*c.CallOptions).GetSchema)], opts...)
+	var resp *apptopologypb.Schema
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = executeRPC(ctx, c.client.GetSchema, req, settings.GRPC, c.logger, "GetSchema")
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func (c *gRPCClient) GetDomain(ctx context.Context, req *apptopologypb.GetDomainRequest, opts ...gax.CallOption) (*apptopologypb.Domain, error) {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GetDomain")
+	}
+	opts = append((*c.CallOptions).GetDomain[0:len((*c.CallOptions).GetDomain):len((*c.CallOptions).GetDomain)], opts...)
+	var resp *apptopologypb.Domain
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = executeRPC(ctx, c.client.GetDomain, req, settings.GRPC, c.logger, "GetDomain")
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func (c *gRPCClient) ListDomains(ctx context.Context, req *apptopologypb.ListDomainsRequest, opts ...gax.CallOption) *DomainIterator {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetParent()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/ListDomains")
+	}
+	opts = append((*c.CallOptions).ListDomains[0:len((*c.CallOptions).ListDomains):len((*c.CallOptions).ListDomains)], opts...)
+	it := &DomainIterator{}
+	req = proto.CloneOf(req)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*apptopologypb.Domain, string, error) {
+		resp := &apptopologypb.ListDomainsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = executeRPC(ctx, c.client.ListDomains, req, settings.GRPC, c.logger, "ListDomains")
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetDomains(), 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
+}
+
+func (c *gRPCClient) GetLocation(ctx context.Context, req *locationpb.GetLocationRequest, opts ...gax.CallOption) (*locationpb.Location, error) {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.location.Locations/GetLocation")
+	}
+	opts = append((*c.CallOptions).GetLocation[0:len((*c.CallOptions).GetLocation):len((*c.CallOptions).GetLocation)], opts...)
+	var resp *locationpb.Location
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = executeRPC(ctx, c.locationsClient.GetLocation, req, settings.GRPC, c.logger, "GetLocation")
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func (c *gRPCClient) ListLocations(ctx context.Context, req *locationpb.ListLocationsRequest, opts ...gax.CallOption) *LocationIterator {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.location.Locations/ListLocations")
+	}
+	opts = append((*c.CallOptions).ListLocations[0:len((*c.CallOptions).ListLocations):len((*c.CallOptions).ListLocations)], opts...)
+	it := &LocationIterator{}
+	req = proto.CloneOf(req)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*locationpb.Location, string, error) {
+		resp := &locationpb.ListLocationsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = executeRPC(ctx, c.locationsClient.ListLocations, req, settings.GRPC, c.logger, "ListLocations")
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetLocations(), 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
+}
+
+func (c *gRPCClient) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest, opts ...gax.CallOption) error {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/CancelOperation")
+	}
+	opts = append((*c.CallOptions).CancelOperation[0:len((*c.CallOptions).CancelOperation):len((*c.CallOptions).CancelOperation)], opts...)
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		_, err = executeRPC(ctx, c.operationsClient.CancelOperation, req, settings.GRPC, c.logger, "CancelOperation")
+		return err
+	}, opts...)
+	return err
+}
+
+func (c *gRPCClient) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest, opts ...gax.CallOption) error {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/DeleteOperation")
+	}
+	opts = append((*c.CallOptions).DeleteOperation[0:len((*c.CallOptions).DeleteOperation):len((*c.CallOptions).DeleteOperation)], opts...)
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		_, err = executeRPC(ctx, c.operationsClient.DeleteOperation, req, settings.GRPC, c.logger, "DeleteOperation")
+		return err
+	}, opts...)
+	return err
+}
+
+func (c *gRPCClient) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/GetOperation")
+	}
+	opts = append((*c.CallOptions).GetOperation[0:len((*c.CallOptions).GetOperation):len((*c.CallOptions).GetOperation)], opts...)
+	var resp *longrunningpb.Operation
+	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		var err error
+		resp, err = executeRPC(ctx, c.operationsClient.GetOperation, req, settings.GRPC, c.logger, "GetOperation")
+		return err
+	}, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func (c *gRPCClient) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest, opts ...gax.CallOption) *OperationIterator {
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	ctx = gax.InsertMetadataIntoOutgoingContext(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/ListOperations")
+	}
+	opts = append((*c.CallOptions).ListOperations[0:len((*c.CallOptions).ListOperations):len((*c.CallOptions).ListOperations)], opts...)
+	it := &OperationIterator{}
+	req = proto.CloneOf(req)
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*longrunningpb.Operation, string, error) {
+		resp := &longrunningpb.ListOperationsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			var err error
+			resp, err = executeRPC(ctx, c.operationsClient.ListOperations, req, settings.GRPC, c.logger, "ListOperations")
+			return err
+		}, opts...)
+		if err != nil {
+			return nil, "", err
+		}
+
+		it.Response = resp
+		return resp.GetOperations(), 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
+}
+
+// GenerateDiscoveredResourcesTopology generate the topology for all resources in the given project. If the
+// project represents an
+// app
+// boundary (at https://cloud.google.com/app-hub/docs/reference/rest/v1/Boundary),
+// the topology is generated for all resources in the boundary.
+func (c *restClient) GenerateDiscoveredResourcesTopology(ctx context.Context, req *apptopologypb.GenerateDiscoveredResourcesTopologyRequest, opts ...gax.CallOption) (*apptopologypb.GenerateDiscoveredResourcesTopologyResponse, error) {
+	m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return nil, err
+	}
+
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return nil, err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v:generate", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GenerateDiscoveredResourcesTopology")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/discoveredResourcesTopology}:generate")
+	}
+	opts = append((*c.CallOptions).GenerateDiscoveredResourcesTopology[0:len((*c.CallOptions).GenerateDiscoveredResourcesTopology):len((*c.CallOptions).GenerateDiscoveredResourcesTopology)], opts...)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	resp := &apptopologypb.GenerateDiscoveredResourcesTopologyResponse{}
+	e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, jsonReq, "GenerateDiscoveredResourcesTopology")
+		if err != nil {
+			return err
+		}
+
+		if err := unm.Unmarshal(buf, resp); err != nil {
+			return err
+		}
+
+		return nil
+	}, opts...)
+	if e != nil {
+		return nil, e
+	}
+	return resp, nil
+}
+
+// GetSchema retrieves the schema for the specified topology domain. The schema
+// defines the NodeTypes and EdgeTypes that are supported in
+// GenerateDiscoveredResourcesTopology requests and responses for a given
+// domain.
+func (c *restClient) GetSchema(ctx context.Context, req *apptopologypb.GetSchemaRequest, opts ...gax.CallOption) (*apptopologypb.Schema, error) {
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return nil, err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GetSchema")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/domains/*/schema}")
+	}
+	opts = append((*c.CallOptions).GetSchema[0:len((*c.CallOptions).GetSchema):len((*c.CallOptions).GetSchema)], opts...)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	resp := &apptopologypb.Schema{}
+	e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "GetSchema")
+		if err != nil {
+			return err
+		}
+
+		if err := unm.Unmarshal(buf, resp); err != nil {
+			return err
+		}
+
+		return nil
+	}, opts...)
+	if e != nil {
+		return nil, e
+	}
+	return resp, nil
+}
+
+// GetDomain retrieves the specified topology domain.
+func (c *restClient) GetDomain(ctx context.Context, req *apptopologypb.GetDomainRequest, opts ...gax.CallOption) (*apptopologypb.Domain, error) {
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return nil, err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "resource_name", fmt.Sprintf("//apptopology.googleapis.com/%v", req.GetName()))
+	}
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.apptopology.v1.AppTopology/GetDomain")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/domains/*}")
+	}
+	opts = append((*c.CallOptions).GetDomain[0:len((*c.CallOptions).GetDomain):len((*c.CallOptions).GetDomain)], opts...)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	resp := &apptopologypb.Domain{}
+	e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "GetDomain")
+		if err != nil {
+			return err
+		}
+
+		if err := unm.Unmarshal(buf, resp); err != nil {
+			return err
+		}
+
+		return nil
+	}, opts...)
+	if e != nil {
+		return nil, e
+	}
+	return resp, nil
+}
+
+// ListDomains lists the topology domains available in a specific location.
+// Only global location is supported.
+func (c *restClient) ListDomains(ctx context.Context, req *apptopologypb.ListDomainsRequest, opts ...gax.CallOption) *DomainIterator {
+	it := &DomainIterator{}
+	req = proto.CloneOf(req)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*apptopologypb.Domain, string, error) {
+		resp := &apptopologypb.ListDomainsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		baseUrl, err := url.Parse(c.endpoint)
+		if err != nil {
+			return nil, "", err
+		}
+		baseUrl.Path += fmt.Sprintf("/v1/%v/domains", req.GetParent())
+
+		params := url.Values{}
+		params.Add("$alt", "json;enum-encoding=int")
+		if req.GetPageSize() != 0 {
+			params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+		}
+		if req.GetPageToken() != "" {
+			params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+		}
+
+		baseUrl.RawQuery = params.Encode()
+
+		// Build HTTP headers from client and context metadata.
+		hds := append(c.xGoogHeaders, "Content-Type", "application/json")
+		headers := gax.BuildHeaders(ctx, hds...)
+		e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			if settings.Path != "" {
+				baseUrl.Path = settings.Path
+			}
+			httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+			if err != nil {
+				return err
+			}
+			httpReq.Header = headers
+
+			buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "ListDomains")
+			if err != nil {
+				return err
+			}
+			if err := unm.Unmarshal(buf, resp); err != nil {
+				return err
+			}
+
+			return nil
+		}, opts...)
+		if e != nil {
+			return nil, "", e
+		}
+		it.Response = resp
+		return resp.GetDomains(), 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
+}
+
+// GetLocation gets information about a location.
+func (c *restClient) GetLocation(ctx context.Context, req *locationpb.GetLocationRequest, opts ...gax.CallOption) (*locationpb.Location, error) {
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return nil, err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.cloud.location.Locations/GetLocation")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*}")
+	}
+	opts = append((*c.CallOptions).GetLocation[0:len((*c.CallOptions).GetLocation):len((*c.CallOptions).GetLocation)], opts...)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	resp := &locationpb.Location{}
+	e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "GetLocation")
+		if err != nil {
+			return err
+		}
+
+		if err := unm.Unmarshal(buf, resp); err != nil {
+			return err
+		}
+
+		return nil
+	}, opts...)
+	if e != nil {
+		return nil, e
+	}
+	return resp, nil
+}
+
+// ListLocations lists information about the supported locations for this service.
+//
+// This method lists locations based on the resource scope provided in
+// the [ListLocationsRequest.name (at http://ListLocationsRequest.name)][google.cloud.location.ListLocationsRequest.name (at http://google.cloud.location.ListLocationsRequest.name)] field: *
+// Global locations: If name is empty, the method lists the
+// public locations available to all projects. * Project-specific
+// locations: If name follows the format
+// projects/{project}, the method lists locations visible to that
+// specific project. This includes public, private, or other
+// project-specific locations enabled for the project.
+//
+// For gRPC and client library implementations, the resource name is
+// passed as the name field. For direct service calls, the resource
+// name is
+// incorporated into the request path based on the specific service
+// implementation and version.
+func (c *restClient) ListLocations(ctx context.Context, req *locationpb.ListLocationsRequest, opts ...gax.CallOption) *LocationIterator {
+	it := &LocationIterator{}
+	req = proto.CloneOf(req)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*locationpb.Location, string, error) {
+		resp := &locationpb.ListLocationsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		baseUrl, err := url.Parse(c.endpoint)
+		if err != nil {
+			return nil, "", err
+		}
+		baseUrl.Path += fmt.Sprintf("/v1/%v/locations", req.GetName())
+
+		params := url.Values{}
+		params.Add("$alt", "json;enum-encoding=int")
+		if req.GetFilter() != "" {
+			params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+		}
+		if req.GetPageSize() != 0 {
+			params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+		}
+		if req.GetPageToken() != "" {
+			params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+		}
+
+		baseUrl.RawQuery = params.Encode()
+
+		// Build HTTP headers from client and context metadata.
+		hds := append(c.xGoogHeaders, "Content-Type", "application/json")
+		headers := gax.BuildHeaders(ctx, hds...)
+		e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			if settings.Path != "" {
+				baseUrl.Path = settings.Path
+			}
+			httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+			if err != nil {
+				return err
+			}
+			httpReq.Header = headers
+
+			buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "ListLocations")
+			if err != nil {
+				return err
+			}
+			if err := unm.Unmarshal(buf, resp); err != nil {
+				return err
+			}
+
+			return nil
+		}, opts...)
+		if e != nil {
+			return nil, "", e
+		}
+		it.Response = resp
+		return resp.GetLocations(), 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
+}
+
+// CancelOperation is a utility method from google.longrunning.Operations.
+func (c *restClient) CancelOperation(ctx context.Context, req *longrunningpb.CancelOperationRequest, opts ...gax.CallOption) error {
+	m := protojson.MarshalOptions{AllowPartial: true, UseEnumNumbers: true}
+	jsonReq, err := m.Marshal(req)
+	if err != nil {
+		return err
+	}
+
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v:cancel", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/CancelOperation")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/operations/*}:cancel")
+	}
+	return gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("POST", baseUrl.String(), bytes.NewReader(jsonReq))
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		_, err = executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, jsonReq, "CancelOperation")
+		return err
+	}, opts...)
+}
+
+// DeleteOperation is a utility method from google.longrunning.Operations.
+func (c *restClient) DeleteOperation(ctx context.Context, req *longrunningpb.DeleteOperationRequest, opts ...gax.CallOption) error {
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/DeleteOperation")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/operations/*}")
+	}
+	return gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("DELETE", baseUrl.String(), nil)
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		_, err = executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "DeleteOperation")
+		return err
+	}, opts...)
+}
+
+// GetOperation is a utility method from google.longrunning.Operations.
+func (c *restClient) GetOperation(ctx context.Context, req *longrunningpb.GetOperationRequest, opts ...gax.CallOption) (*longrunningpb.Operation, error) {
+	baseUrl, err := url.Parse(c.endpoint)
+	if err != nil {
+		return nil, err
+	}
+	baseUrl.Path += fmt.Sprintf("/v1/%v", req.GetName())
+
+	params := url.Values{}
+	params.Add("$alt", "json;enum-encoding=int")
+
+	baseUrl.RawQuery = params.Encode()
+
+	// Build HTTP headers from client and context metadata.
+	hds := []string{"x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName()))}
+
+	hds = append(c.xGoogHeaders, hds...)
+	hds = append(hds, "Content-Type", "application/json")
+	headers := gax.BuildHeaders(ctx, hds...)
+	if gax.IsFeatureEnabled("METRICS") || gax.IsFeatureEnabled("TRACING") || gax.IsFeatureEnabled("LOGGING") {
+		ctx = callctx.WithTelemetryContext(ctx, "rpc_method", "google.longrunning.Operations/GetOperation")
+		ctx = callctx.WithTelemetryContext(ctx, "url_template", "/v1/{name=projects/*/locations/*/operations/*}")
+	}
+	opts = append((*c.CallOptions).GetOperation[0:len((*c.CallOptions).GetOperation):len((*c.CallOptions).GetOperation)], opts...)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	resp := &longrunningpb.Operation{}
+	e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+		if settings.Path != "" {
+			baseUrl.Path = settings.Path
+		}
+		httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+		if err != nil {
+			return err
+		}
+		httpReq = httpReq.WithContext(ctx)
+		httpReq.Header = headers
+
+		buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "GetOperation")
+		if err != nil {
+			return err
+		}
+
+		if err := unm.Unmarshal(buf, resp); err != nil {
+			return err
+		}
+
+		return nil
+	}, opts...)
+	if e != nil {
+		return nil, e
+	}
+	return resp, nil
+}
+
+// ListOperations is a utility method from google.longrunning.Operations.
+func (c *restClient) ListOperations(ctx context.Context, req *longrunningpb.ListOperationsRequest, opts ...gax.CallOption) *OperationIterator {
+	it := &OperationIterator{}
+	req = proto.CloneOf(req)
+	unm := protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
+	it.InternalFetch = func(pageSize int, pageToken string) ([]*longrunningpb.Operation, string, error) {
+		resp := &longrunningpb.ListOperationsResponse{}
+		if pageToken != "" {
+			req.PageToken = pageToken
+		}
+		if pageSize > math.MaxInt32 {
+			req.PageSize = math.MaxInt32
+		} else if pageSize != 0 {
+			req.PageSize = int32(pageSize)
+		}
+		baseUrl, err := url.Parse(c.endpoint)
+		if err != nil {
+			return nil, "", err
+		}
+		baseUrl.Path += fmt.Sprintf("/v1/%v/operations", req.GetName())
+
+		params := url.Values{}
+		params.Add("$alt", "json;enum-encoding=int")
+		if req.GetFilter() != "" {
+			params.Add("filter", fmt.Sprintf("%v", req.GetFilter()))
+		}
+		if req.GetPageSize() != 0 {
+			params.Add("pageSize", fmt.Sprintf("%v", req.GetPageSize()))
+		}
+		if req.GetPageToken() != "" {
+			params.Add("pageToken", fmt.Sprintf("%v", req.GetPageToken()))
+		}
+		if req.GetReturnPartialSuccess() {
+			params.Add("returnPartialSuccess", fmt.Sprintf("%v", req.GetReturnPartialSuccess()))
+		}
+
+		baseUrl.RawQuery = params.Encode()
+
+		// Build HTTP headers from client and context metadata.
+		hds := append(c.xGoogHeaders, "Content-Type", "application/json")
+		headers := gax.BuildHeaders(ctx, hds...)
+		e := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
+			if settings.Path != "" {
+				baseUrl.Path = settings.Path
+			}
+			httpReq, err := http.NewRequest("GET", baseUrl.String(), nil)
+			if err != nil {
+				return err
+			}
+			httpReq.Header = headers
+
+			buf, err := executeHTTPRequest(ctx, c.httpClient, httpReq, c.logger, nil, "ListOperations")
+			if err != nil {
+				return err
+			}
+			if err := unm.Unmarshal(buf, resp); err != nil {
+				return err
+			}
+
+			return nil
+		}, opts...)
+		if e != nil {
+			return nil, "", e
+		}
+		it.Response = resp
+		return resp.GetOperations(), 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
+}
diff --git a/apptopology/apiv1/app_topology_client_example_go123_test.go b/apptopology/apiv1/app_topology_client_example_go123_test.go
new file mode 100644
index 0000000..3fb5c5f
--- /dev/null
+++ b/apptopology/apiv1/app_topology_client_example_go123_test.go
@@ -0,0 +1,106 @@
+// Copyright 2026 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.
+
+//go:build go1.23
+
+package apptopology_test
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+)
+
+func ExampleClient_ListDomains_all() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.ListDomainsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#ListDomainsRequest.
+	}
+	for resp, err := range c.ListDomains(ctx, req).All() {
+		if err != nil {
+			// TODO: Handle error and break/return/continue. Iteration will stop after any error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
+
+func ExampleClient_ListLocations_all() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &locationpb.ListLocationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/location#ListLocationsRequest.
+	}
+	for resp, err := range c.ListLocations(ctx, req).All() {
+		if err != nil {
+			// TODO: Handle error and break/return/continue. Iteration will stop after any error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
+
+func ExampleClient_ListOperations_all() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.ListOperationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#ListOperationsRequest.
+	}
+	for resp, err := range c.ListOperations(ctx, req).All() {
+		if err != nil {
+			// TODO: Handle error and break/return/continue. Iteration will stop after any error.
+		}
+		// TODO: Use resp.
+		_ = resp
+	}
+}
diff --git a/apptopology/apiv1/app_topology_client_example_test.go b/apptopology/apiv1/app_topology_client_example_test.go
new file mode 100644
index 0000000..5412054
--- /dev/null
+++ b/apptopology/apiv1/app_topology_client_example_test.go
@@ -0,0 +1,343 @@
+// Copyright 2026 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 apptopology_test
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+	"google.golang.org/api/iterator"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+)
+
+func ExampleNewClient() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleNewRESTClient() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewRESTClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	// TODO: Use client.
+	_ = c
+}
+
+func ExampleClient_GenerateDiscoveredResourcesTopology() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GenerateDiscoveredResourcesTopologyRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GenerateDiscoveredResourcesTopologyRequest.
+	}
+	resp, err := c.GenerateDiscoveredResourcesTopology(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_GetDomain() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GetDomainRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GetDomainRequest.
+	}
+	resp, err := c.GetDomain(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_GetSchema() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GetSchemaRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GetSchemaRequest.
+	}
+	resp, err := c.GetSchema(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_ListDomains() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.ListDomainsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#ListDomainsRequest.
+	}
+	it := c.ListDomains(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*apptopologypb.ListDomainsResponse)
+	}
+}
+
+func ExampleClient_GetLocation() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &locationpb.GetLocationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/location#GetLocationRequest.
+	}
+	resp, err := c.GetLocation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_ListLocations() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &locationpb.ListLocationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/location#ListLocationsRequest.
+	}
+	it := c.ListLocations(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*locationpb.ListLocationsResponse)
+	}
+}
+
+func ExampleClient_CancelOperation() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.CancelOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#CancelOperationRequest.
+	}
+	err = c.CancelOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+func ExampleClient_DeleteOperation() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.DeleteOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#DeleteOperationRequest.
+	}
+	err = c.DeleteOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+func ExampleClient_GetOperation() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.GetOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#GetOperationRequest.
+	}
+	resp, err := c.GetOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+func ExampleClient_ListOperations() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.ListOperationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#ListOperationsRequest.
+	}
+	it := c.ListOperations(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*longrunningpb.ListOperationsResponse)
+	}
+}
diff --git a/apptopology/apiv1/apptopologypb/graph.pb.go b/apptopology/apiv1/apptopologypb/graph.pb.go
new file mode 100644
index 0000000..c540886
--- /dev/null
+++ b/apptopology/apiv1/apptopologypb/graph.pb.go
@@ -0,0 +1,408 @@
+// Copyright 2026 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
+//
+//     http://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. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.36.11
+// 	protoc        v6.33.2
+// source: google/cloud/apptopology/v1/graph.proto
+
+package apptopologypb
+
+import (
+	reflect "reflect"
+	sync "sync"
+	unsafe "unsafe"
+
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	structpb "google.golang.org/protobuf/types/known/structpb"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Represents a graph structure composed of nodes and edges.
+type Graph struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// A collection of unique nodes that make up the graph.
+	Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
+	// Collection of unique edges connecting the `nodes` in the graph. Both source
+	// and destination nodes for each edges will be present in the `nodes` list.
+	Edges         []*Edge `protobuf:"bytes,2,rep,name=edges,proto3" json:"edges,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Graph) Reset() {
+	*x = Graph{}
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Graph) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Graph) ProtoMessage() {}
+
+func (x *Graph) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Graph.ProtoReflect.Descriptor instead.
+func (*Graph) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_graph_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Graph) GetNodes() []*Node {
+	if x != nil {
+		return x.Nodes
+	}
+	return nil
+}
+
+func (x *Graph) GetEdges() []*Edge {
+	if x != nil {
+		return x.Edges
+	}
+	return nil
+}
+
+// Represents the context of an entity (node or edge) in the graph.
+type EntityContext struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// The primary, namespaced type dictating the node naming format and supported
+	// labels, and defined in the `Schema` (Schema.node_types/edge_types.name),
+	// e.g., `Base/compute.googleapis.com/Instance`.
+	Type          string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *EntityContext) Reset() {
+	*x = EntityContext{}
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *EntityContext) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EntityContext) ProtoMessage() {}
+
+func (x *EntityContext) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EntityContext.ProtoReflect.Descriptor instead.
+func (*EntityContext) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_graph_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *EntityContext) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+// Represents a single node in the graph.
+type Node struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Properties associated with the node.
+	// Refer to https://apptopology.googleapis.com/v1/GetSchema for a detailed
+	// list of node properties.
+	Properties *structpb.Struct `protobuf:"bytes,3,opt,name=properties,proto3" json:"properties,omitempty"`
+	// The global unique name of the node.
+	// For standard Google Cloud Platform resources, this MUST be the canonical
+	// Full Resource Name.
+	//
+	// Examples:
+	//
+	//   - type: compute.googleapis.com/Instance
+	//     name:
+	//     "//compute.googleapis.com/projects/my-project-id/zones/us-central1-a/instances/my-vm-1"
+	//
+	//   - type: container.googleapis.com/Cluster
+	//     name:
+	//     "//container.googleapis.com/projects/my-project-id/locations/us-central1/clusters/my-cluster"
+	Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
+	// Labels attached to the node. Composable, namespaced building blocks that
+	// define core attributes through associated properties. Multiple labels
+	// aggregate to fully specify the functional traits and property schema of the
+	// node type.
+	Labels []string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty"`
+	// The context of the node.
+	Context       *EntityContext `protobuf:"bytes,6,opt,name=context,proto3" json:"context,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Node) Reset() {
+	*x = Node{}
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Node) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Node) ProtoMessage() {}
+
+func (x *Node) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Node.ProtoReflect.Descriptor instead.
+func (*Node) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_graph_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Node) GetProperties() *structpb.Struct {
+	if x != nil {
+		return x.Properties
+	}
+	return nil
+}
+
+func (x *Node) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Node) GetLabels() []string {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *Node) GetContext() *EntityContext {
+	if x != nil {
+		return x.Context
+	}
+	return nil
+}
+
+// Represents a single edge connecting two nodes in the graph.
+type Edge struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Properties associated with the edge.
+	// Refer to https://apptopology.googleapis.com/v1/GetSchema for a detailed
+	// list of edge properties.
+	Properties *structpb.Struct `protobuf:"bytes,5,opt,name=properties,proto3" json:"properties,omitempty"`
+	// The name of the source node for this edge. This is the `name` field in the
+	// Node.
+	SourceNodeName string `protobuf:"bytes,6,opt,name=source_node_name,json=sourceNodeName,proto3" json:"source_node_name,omitempty"`
+	// The name of the destination node for this edge. This is the `name` field in
+	// the Node.
+	DestinationNodeName string `protobuf:"bytes,7,opt,name=destination_node_name,json=destinationNodeName,proto3" json:"destination_node_name,omitempty"`
+	// Labels attached to the edge. Composable, namespaced building blocks that
+	// define core attributes through associated properties. Multiple labels
+	// aggregate to fully specify the functional traits and property schema of the
+	// edge type.
+	Labels []string `protobuf:"bytes,8,rep,name=labels,proto3" json:"labels,omitempty"`
+	// The context of the edge.
+	Context       *EntityContext `protobuf:"bytes,9,opt,name=context,proto3" json:"context,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Edge) Reset() {
+	*x = Edge{}
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Edge) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Edge) ProtoMessage() {}
+
+func (x *Edge) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_graph_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Edge.ProtoReflect.Descriptor instead.
+func (*Edge) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_graph_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Edge) GetProperties() *structpb.Struct {
+	if x != nil {
+		return x.Properties
+	}
+	return nil
+}
+
+func (x *Edge) GetSourceNodeName() string {
+	if x != nil {
+		return x.SourceNodeName
+	}
+	return ""
+}
+
+func (x *Edge) GetDestinationNodeName() string {
+	if x != nil {
+		return x.DestinationNodeName
+	}
+	return ""
+}
+
+func (x *Edge) GetLabels() []string {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *Edge) GetContext() *EntityContext {
+	if x != nil {
+		return x.Context
+	}
+	return nil
+}
+
+var File_google_cloud_apptopology_v1_graph_proto protoreflect.FileDescriptor
+
+const file_google_cloud_apptopology_v1_graph_proto_rawDesc = "" +
+	"\n" +
+	"'google/cloud/apptopology/v1/graph.proto\x12\x1bgoogle.cloud.apptopology.v1\x1a\x1fgoogle/api/field_behavior.proto\x1a\x1cgoogle/protobuf/struct.proto\"y\n" +
+	"\x05Graph\x127\n" +
+	"\x05nodes\x18\x01 \x03(\v2!.google.cloud.apptopology.v1.NodeR\x05nodes\x127\n" +
+	"\x05edges\x18\x02 \x03(\v2!.google.cloud.apptopology.v1.EdgeR\x05edges\"#\n" +
+	"\rEntityContext\x12\x12\n" +
+	"\x04type\x18\x01 \x01(\tR\x04type\"\xb1\x01\n" +
+	"\x04Node\x127\n" +
+	"\n" +
+	"properties\x18\x03 \x01(\v2\x17.google.protobuf.StructR\n" +
+	"properties\x12\x12\n" +
+	"\x04name\x18\x04 \x01(\tR\x04name\x12\x16\n" +
+	"\x06labels\x18\x05 \x03(\tR\x06labels\x12D\n" +
+	"\acontext\x18\x06 \x01(\v2*.google.cloud.apptopology.v1.EntityContextR\acontext\"\xfb\x01\n" +
+	"\x04Edge\x127\n" +
+	"\n" +
+	"properties\x18\x05 \x01(\v2\x17.google.protobuf.StructR\n" +
+	"properties\x12(\n" +
+	"\x10source_node_name\x18\x06 \x01(\tR\x0esourceNodeName\x122\n" +
+	"\x15destination_node_name\x18\a \x01(\tR\x13destinationNodeName\x12\x16\n" +
+	"\x06labels\x18\b \x03(\tR\x06labels\x12D\n" +
+	"\acontext\x18\t \x01(\v2*.google.cloud.apptopology.v1.EntityContextR\acontextB\xcf\x01\n" +
+	"\x1fcom.google.cloud.apptopology.v1B\n" +
+	"GraphProtoP\x01ZAcloud.google.com/go/apptopology/apiv1/apptopologypb;apptopologypb\xaa\x02\x1bGoogle.Cloud.AppTopology.V1\xca\x02\x1bGoogle\\Cloud\\AppTopology\\V1\xea\x02\x1eGoogle::Cloud::AppTopology::V1b\x06proto3"
+
+var (
+	file_google_cloud_apptopology_v1_graph_proto_rawDescOnce sync.Once
+	file_google_cloud_apptopology_v1_graph_proto_rawDescData []byte
+)
+
+func file_google_cloud_apptopology_v1_graph_proto_rawDescGZIP() []byte {
+	file_google_cloud_apptopology_v1_graph_proto_rawDescOnce.Do(func() {
+		file_google_cloud_apptopology_v1_graph_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_graph_proto_rawDesc), len(file_google_cloud_apptopology_v1_graph_proto_rawDesc)))
+	})
+	return file_google_cloud_apptopology_v1_graph_proto_rawDescData
+}
+
+var file_google_cloud_apptopology_v1_graph_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_google_cloud_apptopology_v1_graph_proto_goTypes = []any{
+	(*Graph)(nil),           // 0: google.cloud.apptopology.v1.Graph
+	(*EntityContext)(nil),   // 1: google.cloud.apptopology.v1.EntityContext
+	(*Node)(nil),            // 2: google.cloud.apptopology.v1.Node
+	(*Edge)(nil),            // 3: google.cloud.apptopology.v1.Edge
+	(*structpb.Struct)(nil), // 4: google.protobuf.Struct
+}
+var file_google_cloud_apptopology_v1_graph_proto_depIdxs = []int32{
+	2, // 0: google.cloud.apptopology.v1.Graph.nodes:type_name -> google.cloud.apptopology.v1.Node
+	3, // 1: google.cloud.apptopology.v1.Graph.edges:type_name -> google.cloud.apptopology.v1.Edge
+	4, // 2: google.cloud.apptopology.v1.Node.properties:type_name -> google.protobuf.Struct
+	1, // 3: google.cloud.apptopology.v1.Node.context:type_name -> google.cloud.apptopology.v1.EntityContext
+	4, // 4: google.cloud.apptopology.v1.Edge.properties:type_name -> google.protobuf.Struct
+	1, // 5: google.cloud.apptopology.v1.Edge.context:type_name -> google.cloud.apptopology.v1.EntityContext
+	6, // [6:6] is the sub-list for method output_type
+	6, // [6:6] is the sub-list for method input_type
+	6, // [6:6] is the sub-list for extension type_name
+	6, // [6:6] is the sub-list for extension extendee
+	0, // [0:6] is the sub-list for field type_name
+}
+
+func init() { file_google_cloud_apptopology_v1_graph_proto_init() }
+func file_google_cloud_apptopology_v1_graph_proto_init() {
+	if File_google_cloud_apptopology_v1_graph_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_graph_proto_rawDesc), len(file_google_cloud_apptopology_v1_graph_proto_rawDesc)),
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_cloud_apptopology_v1_graph_proto_goTypes,
+		DependencyIndexes: file_google_cloud_apptopology_v1_graph_proto_depIdxs,
+		MessageInfos:      file_google_cloud_apptopology_v1_graph_proto_msgTypes,
+	}.Build()
+	File_google_cloud_apptopology_v1_graph_proto = out.File
+	file_google_cloud_apptopology_v1_graph_proto_goTypes = nil
+	file_google_cloud_apptopology_v1_graph_proto_depIdxs = nil
+}
diff --git a/apptopology/apiv1/apptopologypb/query.pb.go b/apptopology/apiv1/apptopologypb/query.pb.go
new file mode 100644
index 0000000..a733e64
--- /dev/null
+++ b/apptopology/apiv1/apptopologypb/query.pb.go
@@ -0,0 +1,628 @@
+// Copyright 2026 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
+//
+//     http://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. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.36.11
+// 	protoc        v6.33.2
+// source: google/cloud/apptopology/v1/query.proto
+
+package apptopologypb
+
+import (
+	reflect "reflect"
+	sync "sync"
+	unsafe "unsafe"
+
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// The direction of the edge to match.
+type EdgePattern_Direction int32
+
+const (
+	// Defaults to DIRECTION_UNSPECIFIED.
+	EdgePattern_DIRECTION_UNSPECIFIED EdgePattern_Direction = 0
+	// Match any edge direction.
+	EdgePattern_ANY EdgePattern_Direction = 1
+	// Match the edge direction from source to destination.
+	EdgePattern_TO EdgePattern_Direction = 2
+	// Match the edge direction from destination to source.
+	EdgePattern_FROM EdgePattern_Direction = 3
+)
+
+// Enum value maps for EdgePattern_Direction.
+var (
+	EdgePattern_Direction_name = map[int32]string{
+		0: "DIRECTION_UNSPECIFIED",
+		1: "ANY",
+		2: "TO",
+		3: "FROM",
+	}
+	EdgePattern_Direction_value = map[string]int32{
+		"DIRECTION_UNSPECIFIED": 0,
+		"ANY":                   1,
+		"TO":                    2,
+		"FROM":                  3,
+	}
+)
+
+func (x EdgePattern_Direction) Enum() *EdgePattern_Direction {
+	p := new(EdgePattern_Direction)
+	*p = x
+	return p
+}
+
+func (x EdgePattern_Direction) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (EdgePattern_Direction) Descriptor() protoreflect.EnumDescriptor {
+	return file_google_cloud_apptopology_v1_query_proto_enumTypes[0].Descriptor()
+}
+
+func (EdgePattern_Direction) Type() protoreflect.EnumType {
+	return &file_google_cloud_apptopology_v1_query_proto_enumTypes[0]
+}
+
+func (x EdgePattern_Direction) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use EdgePattern_Direction.Descriptor instead.
+func (EdgePattern_Direction) EnumDescriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{2, 0}
+}
+
+// Recursive graph pattern matcher to select and constrain the returned
+// topology.
+// AppTopology API allows cycle in the graph traversal and will return unique
+// node and edge results in the response.
+// SLO is guaranteed for at most 5 hops in the graph traversal.
+type GraphPattern struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. Pattern matcher to select the starting nodes in the graph.
+	StartingNode *NodePattern `protobuf:"bytes,1,opt,name=starting_node,json=startingNode,proto3" json:"starting_node,omitempty"`
+	// Optional. Pattern matcher to match the connected subgraphs; all of these
+	// are ANDed.
+	Neighbors     []*ConnectedNodePattern `protobuf:"bytes,2,rep,name=neighbors,proto3" json:"neighbors,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *GraphPattern) Reset() {
+	*x = GraphPattern{}
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GraphPattern) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GraphPattern) ProtoMessage() {}
+
+func (x *GraphPattern) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GraphPattern.ProtoReflect.Descriptor instead.
+func (*GraphPattern) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GraphPattern) GetStartingNode() *NodePattern {
+	if x != nil {
+		return x.StartingNode
+	}
+	return nil
+}
+
+func (x *GraphPattern) GetNeighbors() []*ConnectedNodePattern {
+	if x != nil {
+		return x.Neighbors
+	}
+	return nil
+}
+
+// Node pattern matcher to match the node id, labels and properties.
+type NodePattern struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Optional. Represents an identifier to be referenced in
+	// `property_matcher_expr`. For example, an alias for `app` can be referenced
+	// as `app.Base/location="us-central1"`. `alias` must be unique within the
+	// query, otherwise an error will be returned.
+	Alias string `protobuf:"bytes,1,opt,name=alias,proto3" json:"alias,omitempty"`
+	// Optional. Matcher for labels/properties.
+	LabelPropertiesPattern *LabelPropertiesPattern `protobuf:"bytes,3,opt,name=label_properties_pattern,json=labelPropertiesPattern,proto3" json:"label_properties_pattern,omitempty"`
+	unknownFields          protoimpl.UnknownFields
+	sizeCache              protoimpl.SizeCache
+}
+
+func (x *NodePattern) Reset() {
+	*x = NodePattern{}
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *NodePattern) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NodePattern) ProtoMessage() {}
+
+func (x *NodePattern) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use NodePattern.ProtoReflect.Descriptor instead.
+func (*NodePattern) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *NodePattern) GetAlias() string {
+	if x != nil {
+		return x.Alias
+	}
+	return ""
+}
+
+func (x *NodePattern) GetLabelPropertiesPattern() *LabelPropertiesPattern {
+	if x != nil {
+		return x.LabelPropertiesPattern
+	}
+	return nil
+}
+
+// Edge pattern matcher to match the edge direction, labels and properties.
+type EdgePattern struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. The direction of the edge to match.
+	Direction EdgePattern_Direction `protobuf:"varint,1,opt,name=direction,proto3,enum=google.cloud.apptopology.v1.EdgePattern_Direction" json:"direction,omitempty"`
+	// Required. Matcher for labels/properties.
+	LabelPropertiesPattern *LabelPropertiesPattern `protobuf:"bytes,2,opt,name=label_properties_pattern,json=labelPropertiesPattern,proto3" json:"label_properties_pattern,omitempty"`
+	// Optional. Represents an identifier to be referenced in
+	// `property_matcher_expr`. For example, an alias for `edge` can be referenced
+	// as `edge.description = "value_1"`. `alias` must be unique within the query,
+	// otherwise an error will be returned.
+	Alias         string `protobuf:"bytes,3,opt,name=alias,proto3" json:"alias,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *EdgePattern) Reset() {
+	*x = EdgePattern{}
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *EdgePattern) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EdgePattern) ProtoMessage() {}
+
+func (x *EdgePattern) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EdgePattern.ProtoReflect.Descriptor instead.
+func (*EdgePattern) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *EdgePattern) GetDirection() EdgePattern_Direction {
+	if x != nil {
+		return x.Direction
+	}
+	return EdgePattern_DIRECTION_UNSPECIFIED
+}
+
+func (x *EdgePattern) GetLabelPropertiesPattern() *LabelPropertiesPattern {
+	if x != nil {
+		return x.LabelPropertiesPattern
+	}
+	return nil
+}
+
+func (x *EdgePattern) GetAlias() string {
+	if x != nil {
+		return x.Alias
+	}
+	return ""
+}
+
+// Edge pattern matcher to match the edge direction, labels and properties.
+type ConnectedNodePattern struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. To match the edge connected the neighbor subgraph.
+	Edge *EdgePattern `protobuf:"bytes,1,opt,name=edge,proto3" json:"edge,omitempty"`
+	// Required. Recursive matcher to match the neighbor subgraph.
+	Graph         *GraphPattern `protobuf:"bytes,2,opt,name=graph,proto3" json:"graph,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *ConnectedNodePattern) Reset() {
+	*x = ConnectedNodePattern{}
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ConnectedNodePattern) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ConnectedNodePattern) ProtoMessage() {}
+
+func (x *ConnectedNodePattern) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ConnectedNodePattern.ProtoReflect.Descriptor instead.
+func (*ConnectedNodePattern) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ConnectedNodePattern) GetEdge() *EdgePattern {
+	if x != nil {
+		return x.Edge
+	}
+	return nil
+}
+
+func (x *ConnectedNodePattern) GetGraph() *GraphPattern {
+	if x != nil {
+		return x.Graph
+	}
+	return nil
+}
+
+// Matcher for label and property. The matcher accepts both exact match and
+// expression.
+type LabelPropertiesPattern struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. Matcher expression for labels. Allow OR / AND operators;
+	// The syntax is defined by the following grammar:
+	//   - The label expression can use either `OR` or `AND` operator, but not a
+	//     combination of both.
+	//
+	// Example: `AppHub/Application`, `AppHub/Workload OR AppHub/Service`
+	LabelMatcherExpr string `protobuf:"bytes,1,opt,name=label_matcher_expr,json=labelMatcherExpr,proto3" json:"label_matcher_expr,omitempty"`
+	// Optional. The syntax of the filter is defined by the following grammar:
+	// https://google.aip.dev/160.
+	//
+	// Referencing properties of graph elements using traversal operator `.`.
+	// Repeated properties cannot be traversed.
+	// e.g. `e.NodeName`, where `e` is a node or edge alias.
+	//
+	// The following properties are supported for all node and edge types:
+	//
+	// - `Labels`: repeated string property. Can be used to combine conditions
+	// between labels and properties.
+	//
+	//	e.g. `e.Labels : "label_1"` to match a node/edge with label
+	//	`label_1`.
+	//
+	// - `NodeName/EdgeName`: string property. Support for filtering by node or
+	// edge names.
+	//
+	//	e.g. `app.NodeName = "apphub.io/Application"`
+	//
+	// Other properties types can be found at
+	// https://apptopology.googleapis.com/v1/GetSchema
+	//
+	// The following operators are supported on properties:
+	// 1. Checking if a non-repeated property of a graph element is equal to a
+	// scalar value using the equality operator `=`.
+	//   - LHS must be a node/edge property.
+	//   - RHS must be a scalar literal.
+	//   - Supported value types: string (enclosed in double quotes), int, double,
+	//     and boolean.
+	//
+	// e.g. `e.project = "project_1"`
+	//
+	// 2. Checking if a non-repeated property of a graph element satisfies a
+	// condition using the comparison operators `>`, `<`, `>=`, `<=`.
+	//   - LHS must be a node/edge property.
+	//   - RHS must be a scalar literal.
+	//   - Supported value types: string (enclosed in double quotes), int, double.
+	//
+	// e.g. `e.NumericProperty < 0.1`
+	//
+	// 3. Checking if a scalar value is present in a repeated property
+	// HAS operator `:`.
+	//   - LHS must be a repeated property.
+	//   - RHS must be a scalar literal.
+	//   - Supported value types: string (enclosed in double quotes), int, double.
+	//
+	// e.g. `e.Labels : "label_1"`, where `e.Labels` is a repeated string
+	// property.
+	//
+	// 4. Checking if a property is present using HAS_PROPERTY operator `:`.
+	//   - LHS must be a node or edge alias.
+	//   - RHS must be a property name.
+	//
+	// e.g. `e : Base/Location`, where `e` is a node or edge alias.
+	//
+	// 5. Combining multiple filters using logical operators : `AND`, and `OR`.
+	//   - Parentheses must be used to resolve ambiguity.
+	//
+	// e.g. `e.Base/Location = "us-central1" AND e.project = "project_1"`
+	//
+	// 6. The following custom functions are supported:
+	//
+	//   - **EQUALS_ANY(arg1, arg2, arg3, ...)**
+	//
+	//   - Checks if `arg1` (a non-repeated property) equals any of the
+	//     subsequent scalar literal arguments.
+	//
+	//   - arg1: non-repeated property. Supported value types: string
+	//     (enclosed in double quotes), int, double.
+	//
+	//   - arg2, arg3, ...: The remaining arguments are literal values to
+	//     compare against. All the arguments must be of the same type.
+	//
+	//   - e.g. `EQUALS_ANY(e.project, "project_1", "project_2")`
+	//
+	//   - **CONTAINS_ANY(arg1, arg2, arg3, ...)**
+	//
+	//   - Checks if a repeated property has any of the given scalar literals.
+	//     arg1: repeated_property. Supported element types: string
+	//     (enclosed in double quotes), int, double.
+	//
+	//   - arg2, arg3, ...: The remaining arguments are literal values to
+	//     compare against. All the arguments must be of the same type.
+	//
+	//   - e.g. `CONTAINS_ANY(e.folders, "folder_1", "folder_2")`
+	//
+	//   - **CONTAINS_ANY_LESS_THAN(arg1, arg2)**
+	//
+	//   - Checks if a repeated property has any element less than the given
+	//     scalar literal.
+	//
+	//   - arg1: repeated_property. Supported element types are: int,
+	//     double.
+	//
+	//   - arg2: scalar literal
+	//
+	//   - e.g. `CONTAINS_ANY_LESS_THAN(e.NumericProperty, 0.1)`
+	//
+	//   - **CONTAINS_ANY_GREATER_THAN(arg1, arg2)**
+	//
+	//   - Checks if a repeated property has any element greater than the given
+	//     scalar literal.
+	//
+	//   - arg1: repeated_property. Supported element types are: int,
+	//     double.
+	//
+	//   - arg2: scalar literal
+	//
+	//   - e.g. `CONTAINS_ANY_GREATER_THAN(e.NumericProperty, 0.1)`
+	//
+	//   - **CONTAINS_ANY_LESS_OR_EQUAL(arg1, arg2)**
+	//
+	//   - Checks if a repeated property has any element less than or equal to
+	//     the given scalar literal.
+	//
+	//   - arg1: repeated_property. Supported element types are: int,
+	//     double.
+	//
+	//   - arg2: scalar literal
+	//
+	//   - e.g. `CONTAINS_ANY_LESS_OR_EQUAL(e.NumericProperty, 0.1)`
+	//
+	//   - **CONTAINS_ANY_GREATER_OR_EQUAL(arg1, arg2)**
+	//
+	//   - Checks if a repeated property has any element greater than or equal
+	//     to the given scalar literal.
+	//
+	//   - arg1: repeated_property. Supported element types are: int,
+	//     double.
+	//
+	//   - arg2: scalar literal
+	//
+	//   - e.g. `CONTAINS_ANY_GREATER_OR_EQUAL(e.NumericProperty, 0.1)`
+	//
+	// NOTE:
+	//   - For Alert nodes, only the equality operator `=` is supported.
+	//     The expression cannot be a composite boolean expression (i.e., combining
+	//     multiple conditions with AND/OR is not supported; it must be simple).
+	//     e.g. `a.NodeName = "alert-1"` is supported, but
+	//     `a.NodeName = "alert-1" OR a.NodeName = "alert-2"` is not supported.
+	//   - For traffic edges, filters cannot be added.
+	PropertyMatcherExpr string `protobuf:"bytes,2,opt,name=property_matcher_expr,json=propertyMatcherExpr,proto3" json:"property_matcher_expr,omitempty"`
+	unknownFields       protoimpl.UnknownFields
+	sizeCache           protoimpl.SizeCache
+}
+
+func (x *LabelPropertiesPattern) Reset() {
+	*x = LabelPropertiesPattern{}
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *LabelPropertiesPattern) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LabelPropertiesPattern) ProtoMessage() {}
+
+func (x *LabelPropertiesPattern) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_query_proto_msgTypes[4]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LabelPropertiesPattern.ProtoReflect.Descriptor instead.
+func (*LabelPropertiesPattern) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_query_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *LabelPropertiesPattern) GetLabelMatcherExpr() string {
+	if x != nil {
+		return x.LabelMatcherExpr
+	}
+	return ""
+}
+
+func (x *LabelPropertiesPattern) GetPropertyMatcherExpr() string {
+	if x != nil {
+		return x.PropertyMatcherExpr
+	}
+	return ""
+}
+
+var File_google_cloud_apptopology_v1_query_proto protoreflect.FileDescriptor
+
+const file_google_cloud_apptopology_v1_query_proto_rawDesc = "" +
+	"\n" +
+	"'google/cloud/apptopology/v1/query.proto\x12\x1bgoogle.cloud.apptopology.v1\x1a\x1fgoogle/api/field_behavior.proto\"\xb8\x01\n" +
+	"\fGraphPattern\x12R\n" +
+	"\rstarting_node\x18\x01 \x01(\v2(.google.cloud.apptopology.v1.NodePatternB\x03\xe0A\x02R\fstartingNode\x12T\n" +
+	"\tneighbors\x18\x02 \x03(\v21.google.cloud.apptopology.v1.ConnectedNodePatternB\x03\xe0A\x01R\tneighbors\"\x9c\x01\n" +
+	"\vNodePattern\x12\x19\n" +
+	"\x05alias\x18\x01 \x01(\tB\x03\xe0A\x01R\x05alias\x12r\n" +
+	"\x18label_properties_pattern\x18\x03 \x01(\v23.google.cloud.apptopology.v1.LabelPropertiesPatternB\x03\xe0A\x01R\x16labelPropertiesPattern\"\xb6\x02\n" +
+	"\vEdgePattern\x12U\n" +
+	"\tdirection\x18\x01 \x01(\x0e22.google.cloud.apptopology.v1.EdgePattern.DirectionB\x03\xe0A\x02R\tdirection\x12r\n" +
+	"\x18label_properties_pattern\x18\x02 \x01(\v23.google.cloud.apptopology.v1.LabelPropertiesPatternB\x03\xe0A\x02R\x16labelPropertiesPattern\x12\x19\n" +
+	"\x05alias\x18\x03 \x01(\tB\x03\xe0A\x01R\x05alias\"A\n" +
+	"\tDirection\x12\x19\n" +
+	"\x15DIRECTION_UNSPECIFIED\x10\x00\x12\a\n" +
+	"\x03ANY\x10\x01\x12\x06\n" +
+	"\x02TO\x10\x02\x12\b\n" +
+	"\x04FROM\x10\x03\"\x9f\x01\n" +
+	"\x14ConnectedNodePattern\x12A\n" +
+	"\x04edge\x18\x01 \x01(\v2(.google.cloud.apptopology.v1.EdgePatternB\x03\xe0A\x02R\x04edge\x12D\n" +
+	"\x05graph\x18\x02 \x01(\v2).google.cloud.apptopology.v1.GraphPatternB\x03\xe0A\x02R\x05graph\"\x84\x01\n" +
+	"\x16LabelPropertiesPattern\x121\n" +
+	"\x12label_matcher_expr\x18\x01 \x01(\tB\x03\xe0A\x02R\x10labelMatcherExpr\x127\n" +
+	"\x15property_matcher_expr\x18\x02 \x01(\tB\x03\xe0A\x01R\x13propertyMatcherExprB\xcf\x01\n" +
+	"\x1fcom.google.cloud.apptopology.v1B\n" +
+	"QueryProtoP\x01ZAcloud.google.com/go/apptopology/apiv1/apptopologypb;apptopologypb\xaa\x02\x1bGoogle.Cloud.AppTopology.V1\xca\x02\x1bGoogle\\Cloud\\AppTopology\\V1\xea\x02\x1eGoogle::Cloud::AppTopology::V1b\x06proto3"
+
+var (
+	file_google_cloud_apptopology_v1_query_proto_rawDescOnce sync.Once
+	file_google_cloud_apptopology_v1_query_proto_rawDescData []byte
+)
+
+func file_google_cloud_apptopology_v1_query_proto_rawDescGZIP() []byte {
+	file_google_cloud_apptopology_v1_query_proto_rawDescOnce.Do(func() {
+		file_google_cloud_apptopology_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_query_proto_rawDesc), len(file_google_cloud_apptopology_v1_query_proto_rawDesc)))
+	})
+	return file_google_cloud_apptopology_v1_query_proto_rawDescData
+}
+
+var file_google_cloud_apptopology_v1_query_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_google_cloud_apptopology_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_google_cloud_apptopology_v1_query_proto_goTypes = []any{
+	(EdgePattern_Direction)(0),     // 0: google.cloud.apptopology.v1.EdgePattern.Direction
+	(*GraphPattern)(nil),           // 1: google.cloud.apptopology.v1.GraphPattern
+	(*NodePattern)(nil),            // 2: google.cloud.apptopology.v1.NodePattern
+	(*EdgePattern)(nil),            // 3: google.cloud.apptopology.v1.EdgePattern
+	(*ConnectedNodePattern)(nil),   // 4: google.cloud.apptopology.v1.ConnectedNodePattern
+	(*LabelPropertiesPattern)(nil), // 5: google.cloud.apptopology.v1.LabelPropertiesPattern
+}
+var file_google_cloud_apptopology_v1_query_proto_depIdxs = []int32{
+	2, // 0: google.cloud.apptopology.v1.GraphPattern.starting_node:type_name -> google.cloud.apptopology.v1.NodePattern
+	4, // 1: google.cloud.apptopology.v1.GraphPattern.neighbors:type_name -> google.cloud.apptopology.v1.ConnectedNodePattern
+	5, // 2: google.cloud.apptopology.v1.NodePattern.label_properties_pattern:type_name -> google.cloud.apptopology.v1.LabelPropertiesPattern
+	0, // 3: google.cloud.apptopology.v1.EdgePattern.direction:type_name -> google.cloud.apptopology.v1.EdgePattern.Direction
+	5, // 4: google.cloud.apptopology.v1.EdgePattern.label_properties_pattern:type_name -> google.cloud.apptopology.v1.LabelPropertiesPattern
+	3, // 5: google.cloud.apptopology.v1.ConnectedNodePattern.edge:type_name -> google.cloud.apptopology.v1.EdgePattern
+	1, // 6: google.cloud.apptopology.v1.ConnectedNodePattern.graph:type_name -> google.cloud.apptopology.v1.GraphPattern
+	7, // [7:7] is the sub-list for method output_type
+	7, // [7:7] is the sub-list for method input_type
+	7, // [7:7] is the sub-list for extension type_name
+	7, // [7:7] is the sub-list for extension extendee
+	0, // [0:7] is the sub-list for field type_name
+}
+
+func init() { file_google_cloud_apptopology_v1_query_proto_init() }
+func file_google_cloud_apptopology_v1_query_proto_init() {
+	if File_google_cloud_apptopology_v1_query_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_query_proto_rawDesc), len(file_google_cloud_apptopology_v1_query_proto_rawDesc)),
+			NumEnums:      1,
+			NumMessages:   5,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_cloud_apptopology_v1_query_proto_goTypes,
+		DependencyIndexes: file_google_cloud_apptopology_v1_query_proto_depIdxs,
+		EnumInfos:         file_google_cloud_apptopology_v1_query_proto_enumTypes,
+		MessageInfos:      file_google_cloud_apptopology_v1_query_proto_msgTypes,
+	}.Build()
+	File_google_cloud_apptopology_v1_query_proto = out.File
+	file_google_cloud_apptopology_v1_query_proto_goTypes = nil
+	file_google_cloud_apptopology_v1_query_proto_depIdxs = nil
+}
diff --git a/apptopology/apiv1/apptopologypb/schema.pb.go b/apptopology/apiv1/apptopologypb/schema.pb.go
new file mode 100644
index 0000000..a3faea5
--- /dev/null
+++ b/apptopology/apiv1/apptopologypb/schema.pb.go
@@ -0,0 +1,1134 @@
+// Copyright 2026 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
+//
+//     http://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. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.36.11
+// 	protoc        v6.33.2
+// source: google/cloud/apptopology/v1/schema.proto
+
+package apptopologypb
+
+import (
+	reflect "reflect"
+	sync "sync"
+	unsafe "unsafe"
+
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Domain is a pre-defined topology query domain. Each topology domain
+// contains a set of nodes and edges.
+type Domain struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Identifier. The pre-defined topology domain.
+	// Currently only SRE, DEVOPS, and SECURITY are available.
+	// Format: `projects/{project}/locations/{location}/domains/{domain}`
+	Name          string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Domain) Reset() {
+	*x = Domain{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Domain) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Domain) ProtoMessage() {}
+
+func (x *Domain) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Domain.ProtoReflect.Descriptor instead.
+func (*Domain) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Domain) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+// Schema is a collection of supported node & edge labels and properties for an
+// overlay.
+type Schema struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Identifier. The resource name of the schema.
+	// Format:
+	// `projects/{project}/locations/{location}/domains/{domain}/schema`
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// A list of `NodeType`s defined within this schema.
+	// Refer to the documentation of `NodeType` for more details.
+	NodeTypes []*NodeType `protobuf:"bytes,2,rep,name=node_types,json=nodeTypes,proto3" json:"node_types,omitempty"`
+	// A list of `EdgeType`s defined within this schema.
+	// Refer to the documentation of `EdgeType` for more details.
+	EdgeTypes []*EdgeType `protobuf:"bytes,3,rep,name=edge_types,json=edgeTypes,proto3" json:"edge_types,omitempty"`
+	// A list of supported labels and corresponding properties.
+	LabelProperties []*LabelProperties `protobuf:"bytes,4,rep,name=label_properties,json=labelProperties,proto3" json:"label_properties,omitempty"`
+	// Edge rules. These will indicate which node types can be connected and
+	// through what edge type. This is a list of (source_node_type, edge_type,
+	// destination_node_type) tuples.
+	EdgeRules     []*EdgeRule `protobuf:"bytes,5,rep,name=edge_rules,json=edgeRules,proto3" json:"edge_rules,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Schema) Reset() {
+	*x = Schema{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Schema) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Schema) ProtoMessage() {}
+
+func (x *Schema) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Schema.ProtoReflect.Descriptor instead.
+func (*Schema) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Schema) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Schema) GetNodeTypes() []*NodeType {
+	if x != nil {
+		return x.NodeTypes
+	}
+	return nil
+}
+
+func (x *Schema) GetEdgeTypes() []*EdgeType {
+	if x != nil {
+		return x.EdgeTypes
+	}
+	return nil
+}
+
+func (x *Schema) GetLabelProperties() []*LabelProperties {
+	if x != nil {
+		return x.LabelProperties
+	}
+	return nil
+}
+
+func (x *Schema) GetEdgeRules() []*EdgeRule {
+	if x != nil {
+		return x.EdgeRules
+	}
+	return nil
+}
+
+// NodeType defines the schema of a node type in the graph.
+type NodeType struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// REQUIRED
+	// Name of the node type.
+	// This name is used to access the node type while defining the schema.
+	Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	// Labels attached to the node. Composable, namespaced building blocks that
+	// define core attributes through associated properties. Multiple labels
+	// aggregate to fully specify the functional traits and property schema of the
+	// node type.
+	Labels []string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
+	// A human-readable description of the `NodeType`.
+	Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	// A node of this node type can have 0 or more of these labels. These node
+	// objects of this node type will have these labels alongside the
+	// required labels.
+	OptionalLabels []string `protobuf:"bytes,4,rep,name=optional_labels,json=optionalLabels,proto3" json:"optional_labels,omitempty"`
+	unknownFields  protoimpl.UnknownFields
+	sizeCache      protoimpl.SizeCache
+}
+
+func (x *NodeType) Reset() {
+	*x = NodeType{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *NodeType) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NodeType) ProtoMessage() {}
+
+func (x *NodeType) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use NodeType.ProtoReflect.Descriptor instead.
+func (*NodeType) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *NodeType) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *NodeType) GetLabels() []string {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *NodeType) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *NodeType) GetOptionalLabels() []string {
+	if x != nil {
+		return x.OptionalLabels
+	}
+	return nil
+}
+
+// EdgeType defines the schema of an edge type in the graph.
+type EdgeType struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// REQUIRED
+	// Name of the edge type.
+	// This name is used to access the edge type while defining the schema.
+	Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	// Labels attached to the edge. Composable, namespaced building blocks that
+	// define core attributes through associated properties. Multiple labels
+	// aggregate to fully specify the functional traits and property schema of the
+	// edge type.
+	Labels []string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty"`
+	// A human-readable description of the `EdgeType`.
+	Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	// An edge of this edge type can have 0 or more of these labels. These edge
+	// objects of this edge type will have these labels alongside the
+	// required labels.
+	OptionalLabels []string `protobuf:"bytes,4,rep,name=optional_labels,json=optionalLabels,proto3" json:"optional_labels,omitempty"`
+	unknownFields  protoimpl.UnknownFields
+	sizeCache      protoimpl.SizeCache
+}
+
+func (x *EdgeType) Reset() {
+	*x = EdgeType{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *EdgeType) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EdgeType) ProtoMessage() {}
+
+func (x *EdgeType) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EdgeType.ProtoReflect.Descriptor instead.
+func (*EdgeType) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *EdgeType) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *EdgeType) GetLabels() []string {
+	if x != nil {
+		return x.Labels
+	}
+	return nil
+}
+
+func (x *EdgeType) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *EdgeType) GetOptionalLabels() []string {
+	if x != nil {
+		return x.OptionalLabels
+	}
+	return nil
+}
+
+// NodeGroup represents a dynamic collection of nodes that satisfy specific
+// criteria. A node is considered part of this group if it matches the defined
+// constraints.
+type NodeGroup struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Optional. A node must have at least one of these labels to be included in
+	// the group. If empty or unset, this constraint is not applied.
+	AnyLabels     []string `protobuf:"bytes,1,rep,name=any_labels,json=anyLabels,proto3" json:"any_labels,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *NodeGroup) Reset() {
+	*x = NodeGroup{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *NodeGroup) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NodeGroup) ProtoMessage() {}
+
+func (x *NodeGroup) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[4]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use NodeGroup.ProtoReflect.Descriptor instead.
+func (*NodeGroup) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *NodeGroup) GetAnyLabels() []string {
+	if x != nil {
+		return x.AnyLabels
+	}
+	return nil
+}
+
+// EdgeRule defines the connection rules for nodes in the graph.
+type EdgeRule struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Specifies the source criteria for this edge rule.
+	// An edge rule must define its source either statically via a specific
+	// node type, or dynamically via a group of nodes that match given
+	// constraints.
+	//
+	// This takes precedence over the `source_node_type` field.
+	//
+	// Types that are valid to be assigned to SourceNode:
+	//
+	//	*EdgeRule_SrcNodeType
+	//	*EdgeRule_SrcNodeGroup
+	SourceNode isEdgeRule_SourceNode `protobuf_oneof:"source_node"`
+	// Specifies the destination criteria for this edge rule.
+	// An edge rule must define its destination either statically via a specific
+	// node type, or dynamically via a group of nodes that match given
+	// constraints.
+	//
+	// This takes precedence over the `destination_node_type` field.
+	//
+	// Types that are valid to be assigned to DestinationNode:
+	//
+	//	*EdgeRule_DestNodeType
+	//	*EdgeRule_DestNodeGroup
+	DestinationNode isEdgeRule_DestinationNode `protobuf_oneof:"destination_node"`
+	// Optional. Name of the connected edge type.
+	EdgeType      string `protobuf:"bytes,3,opt,name=edge_type,json=edgeType,proto3" json:"edge_type,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *EdgeRule) Reset() {
+	*x = EdgeRule{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *EdgeRule) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EdgeRule) ProtoMessage() {}
+
+func (x *EdgeRule) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[5]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EdgeRule.ProtoReflect.Descriptor instead.
+func (*EdgeRule) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *EdgeRule) GetSourceNode() isEdgeRule_SourceNode {
+	if x != nil {
+		return x.SourceNode
+	}
+	return nil
+}
+
+func (x *EdgeRule) GetSrcNodeType() string {
+	if x != nil {
+		if x, ok := x.SourceNode.(*EdgeRule_SrcNodeType); ok {
+			return x.SrcNodeType
+		}
+	}
+	return ""
+}
+
+func (x *EdgeRule) GetSrcNodeGroup() *NodeGroup {
+	if x != nil {
+		if x, ok := x.SourceNode.(*EdgeRule_SrcNodeGroup); ok {
+			return x.SrcNodeGroup
+		}
+	}
+	return nil
+}
+
+func (x *EdgeRule) GetDestinationNode() isEdgeRule_DestinationNode {
+	if x != nil {
+		return x.DestinationNode
+	}
+	return nil
+}
+
+func (x *EdgeRule) GetDestNodeType() string {
+	if x != nil {
+		if x, ok := x.DestinationNode.(*EdgeRule_DestNodeType); ok {
+			return x.DestNodeType
+		}
+	}
+	return ""
+}
+
+func (x *EdgeRule) GetDestNodeGroup() *NodeGroup {
+	if x != nil {
+		if x, ok := x.DestinationNode.(*EdgeRule_DestNodeGroup); ok {
+			return x.DestNodeGroup
+		}
+	}
+	return nil
+}
+
+func (x *EdgeRule) GetEdgeType() string {
+	if x != nil {
+		return x.EdgeType
+	}
+	return ""
+}
+
+type isEdgeRule_SourceNode interface {
+	isEdgeRule_SourceNode()
+}
+
+type EdgeRule_SrcNodeType struct {
+	// Optional. The specific node type name that acts as the source for this
+	// edge.
+	SrcNodeType string `protobuf:"bytes,4,opt,name=src_node_type,json=srcNodeType,proto3,oneof"`
+}
+
+type EdgeRule_SrcNodeGroup struct {
+	// Optional. A dynamic group of nodes, defined by label constraints, that
+	// can act as the source for this edge.
+	SrcNodeGroup *NodeGroup `protobuf:"bytes,5,opt,name=src_node_group,json=srcNodeGroup,proto3,oneof"`
+}
+
+func (*EdgeRule_SrcNodeType) isEdgeRule_SourceNode() {}
+
+func (*EdgeRule_SrcNodeGroup) isEdgeRule_SourceNode() {}
+
+type isEdgeRule_DestinationNode interface {
+	isEdgeRule_DestinationNode()
+}
+
+type EdgeRule_DestNodeType struct {
+	// Optional. The specific node type name that acts as the destination for
+	// this edge.
+	DestNodeType string `protobuf:"bytes,6,opt,name=dest_node_type,json=destNodeType,proto3,oneof"`
+}
+
+type EdgeRule_DestNodeGroup struct {
+	// Optional. A dynamic group of nodes, defined by label constraints, that
+	// can act as the destination for this edge.
+	DestNodeGroup *NodeGroup `protobuf:"bytes,7,opt,name=dest_node_group,json=destNodeGroup,proto3,oneof"`
+}
+
+func (*EdgeRule_DestNodeType) isEdgeRule_DestinationNode() {}
+
+func (*EdgeRule_DestNodeGroup) isEdgeRule_DestinationNode() {}
+
+// Identifier for the label and corresponding properties.
+type LabelProperties struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Full qualified name of the label.
+	Label string `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
+	// List of properties associated with the label.
+	Properties []*Property `protobuf:"bytes,2,rep,name=properties,proto3" json:"properties,omitempty"`
+	// A human-readable description of the label.
+	Description   string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *LabelProperties) Reset() {
+	*x = LabelProperties{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[6]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *LabelProperties) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LabelProperties) ProtoMessage() {}
+
+func (x *LabelProperties) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[6]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LabelProperties.ProtoReflect.Descriptor instead.
+func (*LabelProperties) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *LabelProperties) GetLabel() string {
+	if x != nil {
+		return x.Label
+	}
+	return ""
+}
+
+func (x *LabelProperties) GetProperties() []*Property {
+	if x != nil {
+		return x.Properties
+	}
+	return nil
+}
+
+func (x *LabelProperties) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+// Property defines the schema of a property in the graph.
+type Property struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// REQUIRED
+	// Value type of the property.
+	//
+	// Types that are valid to be assigned to Value:
+	//
+	//	*Property_StringValue
+	//	*Property_IntValue
+	//	*Property_BoolValue
+	//	*Property_DoubleValue
+	Value isProperty_Value `protobuf_oneof:"value"`
+	// `name` is the key string to identify the property in `Node`s & `Edge`s.
+	// Examples: `ProjectId`, `Base/displayName` etc.
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// A human-readable description of the `PropertyType`, explaining its meaning,
+	// purpose, and any constraints or expectations on its value.
+	Description   string `protobuf:"bytes,10,opt,name=description,proto3" json:"description,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *Property) Reset() {
+	*x = Property{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[7]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Property) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Property) ProtoMessage() {}
+
+func (x *Property) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[7]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Property.ProtoReflect.Descriptor instead.
+func (*Property) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *Property) GetValue() isProperty_Value {
+	if x != nil {
+		return x.Value
+	}
+	return nil
+}
+
+func (x *Property) GetStringValue() *StringValue {
+	if x != nil {
+		if x, ok := x.Value.(*Property_StringValue); ok {
+			return x.StringValue
+		}
+	}
+	return nil
+}
+
+func (x *Property) GetIntValue() *IntValue {
+	if x != nil {
+		if x, ok := x.Value.(*Property_IntValue); ok {
+			return x.IntValue
+		}
+	}
+	return nil
+}
+
+func (x *Property) GetBoolValue() *BoolValue {
+	if x != nil {
+		if x, ok := x.Value.(*Property_BoolValue); ok {
+			return x.BoolValue
+		}
+	}
+	return nil
+}
+
+func (x *Property) GetDoubleValue() *DoubleValue {
+	if x != nil {
+		if x, ok := x.Value.(*Property_DoubleValue); ok {
+			return x.DoubleValue
+		}
+	}
+	return nil
+}
+
+func (x *Property) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Property) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+type isProperty_Value interface {
+	isProperty_Value()
+}
+
+type Property_StringValue struct {
+	// StringValue represents a property that has a string value type.
+	StringValue *StringValue `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"`
+}
+
+type Property_IntValue struct {
+	// IntValue represents a property that has an integer value type.
+	IntValue *IntValue `protobuf:"bytes,4,opt,name=int_value,json=intValue,proto3,oneof"`
+}
+
+type Property_BoolValue struct {
+	// BoolValue represents a property that has a boolean value type.
+	BoolValue *BoolValue `protobuf:"bytes,5,opt,name=bool_value,json=boolValue,proto3,oneof"`
+}
+
+type Property_DoubleValue struct {
+	// DoubleValue represents a property that has a double value type.
+	DoubleValue *DoubleValue `protobuf:"bytes,6,opt,name=double_value,json=doubleValue,proto3,oneof"`
+}
+
+func (*Property_StringValue) isProperty_Value() {}
+
+func (*Property_IntValue) isProperty_Value() {}
+
+func (*Property_BoolValue) isProperty_Value() {}
+
+func (*Property_DoubleValue) isProperty_Value() {}
+
+// StringValue represents a property that has a string value type.
+type StringValue struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// OPTIONAL
+	// Whether the property is repeated.
+	Repeated bool `protobuf:"varint,1,opt,name=repeated,proto3" json:"repeated,omitempty"`
+	// OPTIONAL
+	// Allowed values for the property. If provided, the property value must be
+	// one of the allowed values.
+	AllowedValues []string `protobuf:"bytes,2,rep,name=allowed_values,json=allowedValues,proto3" json:"allowed_values,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *StringValue) Reset() {
+	*x = StringValue{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[8]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *StringValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StringValue) ProtoMessage() {}
+
+func (x *StringValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[8]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use StringValue.ProtoReflect.Descriptor instead.
+func (*StringValue) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *StringValue) GetRepeated() bool {
+	if x != nil {
+		return x.Repeated
+	}
+	return false
+}
+
+func (x *StringValue) GetAllowedValues() []string {
+	if x != nil {
+		return x.AllowedValues
+	}
+	return nil
+}
+
+// IntValue represents a property that has an integer value type.
+type IntValue struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// OPTIONAL
+	// Whether the property is repeated.
+	Repeated bool `protobuf:"varint,1,opt,name=repeated,proto3" json:"repeated,omitempty"`
+	// OPTIONAL
+	// Allowed values for the property. If provided, the property value must be
+	// one of the allowed values.
+	AllowedValues []int64 `protobuf:"varint,2,rep,packed,name=allowed_values,json=allowedValues,proto3" json:"allowed_values,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *IntValue) Reset() {
+	*x = IntValue{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[9]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *IntValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*IntValue) ProtoMessage() {}
+
+func (x *IntValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[9]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use IntValue.ProtoReflect.Descriptor instead.
+func (*IntValue) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *IntValue) GetRepeated() bool {
+	if x != nil {
+		return x.Repeated
+	}
+	return false
+}
+
+func (x *IntValue) GetAllowedValues() []int64 {
+	if x != nil {
+		return x.AllowedValues
+	}
+	return nil
+}
+
+// BoolValue represents a property that has a boolean value type.
+type BoolValue struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// OPTIONAL
+	// Whether the property is repeated.
+	Repeated bool `protobuf:"varint,1,opt,name=repeated,proto3" json:"repeated,omitempty"`
+	// OPTIONAL
+	// Allowed values for the property. If provided, the property value must be
+	// one of the allowed values.
+	AllowedValues []bool `protobuf:"varint,2,rep,packed,name=allowed_values,json=allowedValues,proto3" json:"allowed_values,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *BoolValue) Reset() {
+	*x = BoolValue{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[10]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *BoolValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BoolValue) ProtoMessage() {}
+
+func (x *BoolValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[10]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BoolValue.ProtoReflect.Descriptor instead.
+func (*BoolValue) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *BoolValue) GetRepeated() bool {
+	if x != nil {
+		return x.Repeated
+	}
+	return false
+}
+
+func (x *BoolValue) GetAllowedValues() []bool {
+	if x != nil {
+		return x.AllowedValues
+	}
+	return nil
+}
+
+// DoubleValue represents a property that has a double value type.
+type DoubleValue struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// OPTIONAL
+	// Whether the property is repeated.
+	Repeated bool `protobuf:"varint,1,opt,name=repeated,proto3" json:"repeated,omitempty"`
+	// OPTIONAL
+	// Allowed values for the property. If provided, the property value must be
+	// one of the allowed values.
+	AllowedValues []float64 `protobuf:"fixed64,2,rep,packed,name=allowed_values,json=allowedValues,proto3" json:"allowed_values,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *DoubleValue) Reset() {
+	*x = DoubleValue{}
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[11]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *DoubleValue) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DoubleValue) ProtoMessage() {}
+
+func (x *DoubleValue) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_schema_proto_msgTypes[11]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DoubleValue.ProtoReflect.Descriptor instead.
+func (*DoubleValue) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *DoubleValue) GetRepeated() bool {
+	if x != nil {
+		return x.Repeated
+	}
+	return false
+}
+
+func (x *DoubleValue) GetAllowedValues() []float64 {
+	if x != nil {
+		return x.AllowedValues
+	}
+	return nil
+}
+
+var File_google_cloud_apptopology_v1_schema_proto protoreflect.FileDescriptor
+
+const file_google_cloud_apptopology_v1_schema_proto_rawDesc = "" +
+	"\n" +
+	"(google/cloud/apptopology/v1/schema.proto\x12\x1bgoogle.cloud.apptopology.v1\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\"\x94\x01\n" +
+	"\x06Domain\x12\x17\n" +
+	"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name:q\xeaAn\n" +
+	"!apptopology.googleapis.com/Domain\x128projects/{project}/locations/{location}/domains/{domain}*\adomains2\x06domain\"\xc6\x03\n" +
+	"\x06Schema\x12\x17\n" +
+	"\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12D\n" +
+	"\n" +
+	"node_types\x18\x02 \x03(\v2%.google.cloud.apptopology.v1.NodeTypeR\tnodeTypes\x12D\n" +
+	"\n" +
+	"edge_types\x18\x03 \x03(\v2%.google.cloud.apptopology.v1.EdgeTypeR\tedgeTypes\x12W\n" +
+	"\x10label_properties\x18\x04 \x03(\v2,.google.cloud.apptopology.v1.LabelPropertiesR\x0flabelProperties\x12D\n" +
+	"\n" +
+	"edge_rules\x18\x05 \x03(\v2%.google.cloud.apptopology.v1.EdgeRuleR\tedgeRules:x\xeaAu\n" +
+	"!apptopology.googleapis.com/Schema\x12?projects/{project}/locations/{location}/domains/{domain}/schema*\aschemas2\x06schema\"\x81\x01\n" +
+	"\bNodeType\x12\x12\n" +
+	"\x04type\x18\x01 \x01(\tR\x04type\x12\x16\n" +
+	"\x06labels\x18\x02 \x03(\tR\x06labels\x12 \n" +
+	"\vdescription\x18\x03 \x01(\tR\vdescription\x12'\n" +
+	"\x0foptional_labels\x18\x04 \x03(\tR\x0eoptionalLabels\"\x81\x01\n" +
+	"\bEdgeType\x12\x12\n" +
+	"\x04type\x18\x01 \x01(\tR\x04type\x12\x16\n" +
+	"\x06labels\x18\x02 \x03(\tR\x06labels\x12 \n" +
+	"\vdescription\x18\x03 \x01(\tR\vdescription\x12'\n" +
+	"\x0foptional_labels\x18\x04 \x03(\tR\x0eoptionalLabels\"/\n" +
+	"\tNodeGroup\x12\"\n" +
+	"\n" +
+	"any_labels\x18\x01 \x03(\tB\x03\xe0A\x01R\tanyLabels\"\xd3\x02\n" +
+	"\bEdgeRule\x12)\n" +
+	"\rsrc_node_type\x18\x04 \x01(\tB\x03\xe0A\x01H\x00R\vsrcNodeType\x12S\n" +
+	"\x0esrc_node_group\x18\x05 \x01(\v2&.google.cloud.apptopology.v1.NodeGroupB\x03\xe0A\x01H\x00R\fsrcNodeGroup\x12+\n" +
+	"\x0edest_node_type\x18\x06 \x01(\tB\x03\xe0A\x01H\x01R\fdestNodeType\x12U\n" +
+	"\x0fdest_node_group\x18\a \x01(\v2&.google.cloud.apptopology.v1.NodeGroupB\x03\xe0A\x01H\x01R\rdestNodeGroup\x12 \n" +
+	"\tedge_type\x18\x03 \x01(\tB\x03\xe0A\x01R\bedgeTypeB\r\n" +
+	"\vsource_nodeB\x12\n" +
+	"\x10destination_node\"\x90\x01\n" +
+	"\x0fLabelProperties\x12\x14\n" +
+	"\x05label\x18\x01 \x01(\tR\x05label\x12E\n" +
+	"\n" +
+	"properties\x18\x02 \x03(\v2%.google.cloud.apptopology.v1.PropertyR\n" +
+	"properties\x12 \n" +
+	"\vdescription\x18\x03 \x01(\tR\vdescription\"\xf6\x02\n" +
+	"\bProperty\x12M\n" +
+	"\fstring_value\x18\x03 \x01(\v2(.google.cloud.apptopology.v1.StringValueH\x00R\vstringValue\x12D\n" +
+	"\tint_value\x18\x04 \x01(\v2%.google.cloud.apptopology.v1.IntValueH\x00R\bintValue\x12G\n" +
+	"\n" +
+	"bool_value\x18\x05 \x01(\v2&.google.cloud.apptopology.v1.BoolValueH\x00R\tboolValue\x12M\n" +
+	"\fdouble_value\x18\x06 \x01(\v2(.google.cloud.apptopology.v1.DoubleValueH\x00R\vdoubleValue\x12\x12\n" +
+	"\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
+	"\vdescription\x18\n" +
+	" \x01(\tR\vdescriptionB\a\n" +
+	"\x05value\"P\n" +
+	"\vStringValue\x12\x1a\n" +
+	"\brepeated\x18\x01 \x01(\bR\brepeated\x12%\n" +
+	"\x0eallowed_values\x18\x02 \x03(\tR\rallowedValues\"M\n" +
+	"\bIntValue\x12\x1a\n" +
+	"\brepeated\x18\x01 \x01(\bR\brepeated\x12%\n" +
+	"\x0eallowed_values\x18\x02 \x03(\x03R\rallowedValues\"N\n" +
+	"\tBoolValue\x12\x1a\n" +
+	"\brepeated\x18\x01 \x01(\bR\brepeated\x12%\n" +
+	"\x0eallowed_values\x18\x02 \x03(\bR\rallowedValues\"P\n" +
+	"\vDoubleValue\x12\x1a\n" +
+	"\brepeated\x18\x01 \x01(\bR\brepeated\x12%\n" +
+	"\x0eallowed_values\x18\x02 \x03(\x01R\rallowedValuesB\xd0\x01\n" +
+	"\x1fcom.google.cloud.apptopology.v1B\vSchemaProtoP\x01ZAcloud.google.com/go/apptopology/apiv1/apptopologypb;apptopologypb\xaa\x02\x1bGoogle.Cloud.AppTopology.V1\xca\x02\x1bGoogle\\Cloud\\AppTopology\\V1\xea\x02\x1eGoogle::Cloud::AppTopology::V1b\x06proto3"
+
+var (
+	file_google_cloud_apptopology_v1_schema_proto_rawDescOnce sync.Once
+	file_google_cloud_apptopology_v1_schema_proto_rawDescData []byte
+)
+
+func file_google_cloud_apptopology_v1_schema_proto_rawDescGZIP() []byte {
+	file_google_cloud_apptopology_v1_schema_proto_rawDescOnce.Do(func() {
+		file_google_cloud_apptopology_v1_schema_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_schema_proto_rawDesc), len(file_google_cloud_apptopology_v1_schema_proto_rawDesc)))
+	})
+	return file_google_cloud_apptopology_v1_schema_proto_rawDescData
+}
+
+var file_google_cloud_apptopology_v1_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
+var file_google_cloud_apptopology_v1_schema_proto_goTypes = []any{
+	(*Domain)(nil),          // 0: google.cloud.apptopology.v1.Domain
+	(*Schema)(nil),          // 1: google.cloud.apptopology.v1.Schema
+	(*NodeType)(nil),        // 2: google.cloud.apptopology.v1.NodeType
+	(*EdgeType)(nil),        // 3: google.cloud.apptopology.v1.EdgeType
+	(*NodeGroup)(nil),       // 4: google.cloud.apptopology.v1.NodeGroup
+	(*EdgeRule)(nil),        // 5: google.cloud.apptopology.v1.EdgeRule
+	(*LabelProperties)(nil), // 6: google.cloud.apptopology.v1.LabelProperties
+	(*Property)(nil),        // 7: google.cloud.apptopology.v1.Property
+	(*StringValue)(nil),     // 8: google.cloud.apptopology.v1.StringValue
+	(*IntValue)(nil),        // 9: google.cloud.apptopology.v1.IntValue
+	(*BoolValue)(nil),       // 10: google.cloud.apptopology.v1.BoolValue
+	(*DoubleValue)(nil),     // 11: google.cloud.apptopology.v1.DoubleValue
+}
+var file_google_cloud_apptopology_v1_schema_proto_depIdxs = []int32{
+	2,  // 0: google.cloud.apptopology.v1.Schema.node_types:type_name -> google.cloud.apptopology.v1.NodeType
+	3,  // 1: google.cloud.apptopology.v1.Schema.edge_types:type_name -> google.cloud.apptopology.v1.EdgeType
+	6,  // 2: google.cloud.apptopology.v1.Schema.label_properties:type_name -> google.cloud.apptopology.v1.LabelProperties
+	5,  // 3: google.cloud.apptopology.v1.Schema.edge_rules:type_name -> google.cloud.apptopology.v1.EdgeRule
+	4,  // 4: google.cloud.apptopology.v1.EdgeRule.src_node_group:type_name -> google.cloud.apptopology.v1.NodeGroup
+	4,  // 5: google.cloud.apptopology.v1.EdgeRule.dest_node_group:type_name -> google.cloud.apptopology.v1.NodeGroup
+	7,  // 6: google.cloud.apptopology.v1.LabelProperties.properties:type_name -> google.cloud.apptopology.v1.Property
+	8,  // 7: google.cloud.apptopology.v1.Property.string_value:type_name -> google.cloud.apptopology.v1.StringValue
+	9,  // 8: google.cloud.apptopology.v1.Property.int_value:type_name -> google.cloud.apptopology.v1.IntValue
+	10, // 9: google.cloud.apptopology.v1.Property.bool_value:type_name -> google.cloud.apptopology.v1.BoolValue
+	11, // 10: google.cloud.apptopology.v1.Property.double_value:type_name -> google.cloud.apptopology.v1.DoubleValue
+	11, // [11:11] is the sub-list for method output_type
+	11, // [11:11] is the sub-list for method input_type
+	11, // [11:11] is the sub-list for extension type_name
+	11, // [11:11] is the sub-list for extension extendee
+	0,  // [0:11] is the sub-list for field type_name
+}
+
+func init() { file_google_cloud_apptopology_v1_schema_proto_init() }
+func file_google_cloud_apptopology_v1_schema_proto_init() {
+	if File_google_cloud_apptopology_v1_schema_proto != nil {
+		return
+	}
+	file_google_cloud_apptopology_v1_schema_proto_msgTypes[5].OneofWrappers = []any{
+		(*EdgeRule_SrcNodeType)(nil),
+		(*EdgeRule_SrcNodeGroup)(nil),
+		(*EdgeRule_DestNodeType)(nil),
+		(*EdgeRule_DestNodeGroup)(nil),
+	}
+	file_google_cloud_apptopology_v1_schema_proto_msgTypes[7].OneofWrappers = []any{
+		(*Property_StringValue)(nil),
+		(*Property_IntValue)(nil),
+		(*Property_BoolValue)(nil),
+		(*Property_DoubleValue)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_schema_proto_rawDesc), len(file_google_cloud_apptopology_v1_schema_proto_rawDesc)),
+			NumEnums:      0,
+			NumMessages:   12,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_cloud_apptopology_v1_schema_proto_goTypes,
+		DependencyIndexes: file_google_cloud_apptopology_v1_schema_proto_depIdxs,
+		MessageInfos:      file_google_cloud_apptopology_v1_schema_proto_msgTypes,
+	}.Build()
+	File_google_cloud_apptopology_v1_schema_proto = out.File
+	file_google_cloud_apptopology_v1_schema_proto_goTypes = nil
+	file_google_cloud_apptopology_v1_schema_proto_depIdxs = nil
+}
diff --git a/apptopology/apiv1/apptopologypb/service.pb.go b/apptopology/apiv1/apptopologypb/service.pb.go
new file mode 100644
index 0000000..b886c90
--- /dev/null
+++ b/apptopology/apiv1/apptopologypb/service.pb.go
@@ -0,0 +1,633 @@
+// Copyright 2026 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
+//
+//     http://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. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.36.11
+// 	protoc        v6.33.2
+// source: google/cloud/apptopology/v1/service.proto
+
+package apptopologypb
+
+import (
+	reflect "reflect"
+	sync "sync"
+	unsafe "unsafe"
+
+	_ "google.golang.org/genproto/googleapis/api/annotations"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Represents the metadata of the long-running operation.
+type OperationMetadata struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Output only. The time the operation was created.
+	CreateTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"`
+	// Output only. The time the operation finished running.
+	EndTime *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"`
+	// Output only. Server-defined resource path for the target of the operation.
+	Target string `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"`
+	// Output only. Name of the verb executed by the operation.
+	Verb string `protobuf:"bytes,4,opt,name=verb,proto3" json:"verb,omitempty"`
+	// Output only. Human-readable status of the operation, if any.
+	StatusMessage string `protobuf:"bytes,5,opt,name=status_message,json=statusMessage,proto3" json:"status_message,omitempty"`
+	// Output only. Identifies whether the user has requested cancellation
+	// of the operation. Operations that have been cancelled successfully
+	// have
+	// [google.longrunning.Operation.error][google.longrunning.Operation.error]
+	// value with a [google.rpc.Status.code][google.rpc.Status.code] of `1`,
+	// corresponding to `Code.CANCELLED`.
+	RequestedCancellation bool `protobuf:"varint,6,opt,name=requested_cancellation,json=requestedCancellation,proto3" json:"requested_cancellation,omitempty"`
+	// Output only. API version used to start the operation.
+	ApiVersion    string `protobuf:"bytes,7,opt,name=api_version,json=apiVersion,proto3" json:"api_version,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *OperationMetadata) Reset() {
+	*x = OperationMetadata{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *OperationMetadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OperationMetadata) ProtoMessage() {}
+
+func (x *OperationMetadata) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OperationMetadata.ProtoReflect.Descriptor instead.
+func (*OperationMetadata) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *OperationMetadata) GetCreateTime() *timestamppb.Timestamp {
+	if x != nil {
+		return x.CreateTime
+	}
+	return nil
+}
+
+func (x *OperationMetadata) GetEndTime() *timestamppb.Timestamp {
+	if x != nil {
+		return x.EndTime
+	}
+	return nil
+}
+
+func (x *OperationMetadata) GetTarget() string {
+	if x != nil {
+		return x.Target
+	}
+	return ""
+}
+
+func (x *OperationMetadata) GetVerb() string {
+	if x != nil {
+		return x.Verb
+	}
+	return ""
+}
+
+func (x *OperationMetadata) GetStatusMessage() string {
+	if x != nil {
+		return x.StatusMessage
+	}
+	return ""
+}
+
+func (x *OperationMetadata) GetRequestedCancellation() bool {
+	if x != nil {
+		return x.RequestedCancellation
+	}
+	return false
+}
+
+func (x *OperationMetadata) GetApiVersion() string {
+	if x != nil {
+		return x.ApiVersion
+	}
+	return ""
+}
+
+// Request for GenerateDiscoveredResourcesTopology.
+type GenerateDiscoveredResourcesTopologyRequest struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Query the topology by building a graph pattern filter or pre-defined
+	// topology view.
+	//
+	// Types that are valid to be assigned to Query:
+	//
+	//	*GenerateDiscoveredResourcesTopologyRequest_Filter
+	Query isGenerateDiscoveredResourcesTopologyRequest_Query `protobuf_oneof:"query"`
+	// Required. The project to query discoverable resources on.
+	// Expected format:
+	// `projects/{project}/locations/{location}/discoveredResourcesTopology`.
+	// Only `global` location is supported.
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Required. The full resource name of the domain of the app topology.
+	// Format: `projects/{project}/locations/{location}/domains/{domain}`
+	// Caller must have apptopology.domains.get permission on each of the domains.
+	TopologyDomains []string `protobuf:"bytes,2,rep,name=topology_domains,json=topologyDomains,proto3" json:"topology_domains,omitempty"`
+	unknownFields   protoimpl.UnknownFields
+	sizeCache       protoimpl.SizeCache
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) Reset() {
+	*x = GenerateDiscoveredResourcesTopologyRequest{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GenerateDiscoveredResourcesTopologyRequest) ProtoMessage() {}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GenerateDiscoveredResourcesTopologyRequest.ProtoReflect.Descriptor instead.
+func (*GenerateDiscoveredResourcesTopologyRequest) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) GetQuery() isGenerateDiscoveredResourcesTopologyRequest_Query {
+	if x != nil {
+		return x.Query
+	}
+	return nil
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) GetFilter() *GraphPattern {
+	if x != nil {
+		if x, ok := x.Query.(*GenerateDiscoveredResourcesTopologyRequest_Filter); ok {
+			return x.Filter
+		}
+	}
+	return nil
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *GenerateDiscoveredResourcesTopologyRequest) GetTopologyDomains() []string {
+	if x != nil {
+		return x.TopologyDomains
+	}
+	return nil
+}
+
+type isGenerateDiscoveredResourcesTopologyRequest_Query interface {
+	isGenerateDiscoveredResourcesTopologyRequest_Query()
+}
+
+type GenerateDiscoveredResourcesTopologyRequest_Filter struct {
+	// Filters for the topology nodes and edges; Detail format see GraphPattern
+	// proto. A separate 'LookupSchema' method will be added that will return
+	// the necessary information to be able to construct these filters.
+	Filter *GraphPattern `protobuf:"bytes,3,opt,name=filter,proto3,oneof"`
+}
+
+func (*GenerateDiscoveredResourcesTopologyRequest_Filter) isGenerateDiscoveredResourcesTopologyRequest_Query() {
+}
+
+// Response for GenerateDiscoveredResourcesTopology.
+type GenerateDiscoveredResourcesTopologyResponse struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// The generated topology graph.
+	Graph         *Graph `protobuf:"bytes,1,opt,name=graph,proto3" json:"graph,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *GenerateDiscoveredResourcesTopologyResponse) Reset() {
+	*x = GenerateDiscoveredResourcesTopologyResponse{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GenerateDiscoveredResourcesTopologyResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GenerateDiscoveredResourcesTopologyResponse) ProtoMessage() {}
+
+func (x *GenerateDiscoveredResourcesTopologyResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GenerateDiscoveredResourcesTopologyResponse.ProtoReflect.Descriptor instead.
+func (*GenerateDiscoveredResourcesTopologyResponse) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *GenerateDiscoveredResourcesTopologyResponse) GetGraph() *Graph {
+	if x != nil {
+		return x.Graph
+	}
+	return nil
+}
+
+// Request for GetSchema.
+type GetSchemaRequest struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. The name of the singleton domain schema resource.
+	// Format: `projects/{project}/locations/{location}/domains/{domain}/schema`
+	Name          string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *GetSchemaRequest) Reset() {
+	*x = GetSchemaRequest{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetSchemaRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetSchemaRequest) ProtoMessage() {}
+
+func (x *GetSchemaRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetSchemaRequest.ProtoReflect.Descriptor instead.
+func (*GetSchemaRequest) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *GetSchemaRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+// Request for GetDomain.
+type GetDomainRequest struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. The name of the domain to retrieve.
+	// Format: `projects/{project}/locations/{location}/domains/{domain}`
+	Name          string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *GetDomainRequest) Reset() {
+	*x = GetDomainRequest{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetDomainRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetDomainRequest) ProtoMessage() {}
+
+func (x *GetDomainRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[4]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetDomainRequest.ProtoReflect.Descriptor instead.
+func (*GetDomainRequest) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GetDomainRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+// Request for ListDomains.
+type ListDomainsRequest struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// Required. The parent location to list domains for.
+	// Format: `projects/{project}/locations/{location}`
+	// Only `global` location is supported.
+	Parent string `protobuf:"bytes,1,opt,name=parent,proto3" json:"parent,omitempty"`
+	// Optional. The maximum number of domains to return. The service may return
+	// fewer than this value. If unspecified, at most 50 domains will be returned.
+	// The maximum value is 1000; values above 1000 will be coerced to 1000.
+	PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
+	// Optional. A page token, received from a previous `ListDomains` call.
+	// Provide this to retrieve the subsequent page.
+	//
+	// When paginating, all other parameters provided to `ListDomains` must match
+	// the call that provided the page token.
+	PageToken     string `protobuf:"bytes,3,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *ListDomainsRequest) Reset() {
+	*x = ListDomainsRequest{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ListDomainsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListDomainsRequest) ProtoMessage() {}
+
+func (x *ListDomainsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[5]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListDomainsRequest.ProtoReflect.Descriptor instead.
+func (*ListDomainsRequest) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ListDomainsRequest) GetParent() string {
+	if x != nil {
+		return x.Parent
+	}
+	return ""
+}
+
+func (x *ListDomainsRequest) GetPageSize() int32 {
+	if x != nil {
+		return x.PageSize
+	}
+	return 0
+}
+
+func (x *ListDomainsRequest) GetPageToken() string {
+	if x != nil {
+		return x.PageToken
+	}
+	return ""
+}
+
+// Response for ListDomains.
+type ListDomainsResponse struct {
+	state protoimpl.MessageState `protogen:"open.v1"`
+	// The domains in the specified location.
+	Domains []*Domain `protobuf:"bytes,1,rep,name=domains,proto3" json:"domains,omitempty"`
+	// A token that can be sent as `page_token` to retrieve the next page.
+	// If this field is omitted, there are no subsequent pages.
+	NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *ListDomainsResponse) Reset() {
+	*x = ListDomainsResponse{}
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[6]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ListDomainsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListDomainsResponse) ProtoMessage() {}
+
+func (x *ListDomainsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_google_cloud_apptopology_v1_service_proto_msgTypes[6]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListDomainsResponse.ProtoReflect.Descriptor instead.
+func (*ListDomainsResponse) Descriptor() ([]byte, []int) {
+	return file_google_cloud_apptopology_v1_service_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *ListDomainsResponse) GetDomains() []*Domain {
+	if x != nil {
+		return x.Domains
+	}
+	return nil
+}
+
+func (x *ListDomainsResponse) GetNextPageToken() string {
+	if x != nil {
+		return x.NextPageToken
+	}
+	return ""
+}
+
+var File_google_cloud_apptopology_v1_service_proto protoreflect.FileDescriptor
+
+const file_google_cloud_apptopology_v1_service_proto_rawDesc = "" +
+	"\n" +
+	")google/cloud/apptopology/v1/service.proto\x12\x1bgoogle.cloud.apptopology.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/api/resource.proto\x1a'google/cloud/apptopology/v1/graph.proto\x1a'google/cloud/apptopology/v1/query.proto\x1a(google/cloud/apptopology/v1/schema.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xd5\x02\n" +
+	"\x11OperationMetadata\x12@\n" +
+	"\vcreate_time\x18\x01 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" +
+	"createTime\x12:\n" +
+	"\bend_time\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\aendTime\x12\x1b\n" +
+	"\x06target\x18\x03 \x01(\tB\x03\xe0A\x03R\x06target\x12\x17\n" +
+	"\x04verb\x18\x04 \x01(\tB\x03\xe0A\x03R\x04verb\x12*\n" +
+	"\x0estatus_message\x18\x05 \x01(\tB\x03\xe0A\x03R\rstatusMessage\x12:\n" +
+	"\x16requested_cancellation\x18\x06 \x01(\bB\x03\xe0A\x03R\x15requestedCancellation\x12$\n" +
+	"\vapi_version\x18\a \x01(\tB\x03\xe0A\x03R\n" +
+	"apiVersion\"\xa4\x02\n" +
+	"*GenerateDiscoveredResourcesTopologyRequest\x12C\n" +
+	"\x06filter\x18\x03 \x01(\v2).google.cloud.apptopology.v1.GraphPatternH\x00R\x06filter\x12R\n" +
+	"\x04name\x18\x01 \x01(\tB>\xe0A\x02\xfaA8\n" +
+	"6apptopology.googleapis.com/DiscoveredResourcesTopologyR\x04name\x12T\n" +
+	"\x10topology_domains\x18\x02 \x03(\tB)\xe0A\x02\xfaA#\n" +
+	"!apptopology.googleapis.com/DomainR\x0ftopologyDomainsB\a\n" +
+	"\x05query\"g\n" +
+	"+GenerateDiscoveredResourcesTopologyResponse\x128\n" +
+	"\x05graph\x18\x01 \x01(\v2\".google.cloud.apptopology.v1.GraphR\x05graph\"Q\n" +
+	"\x10GetSchemaRequest\x12=\n" +
+	"\x04name\x18\x01 \x01(\tB)\xe0A\x02\xfaA#\n" +
+	"!apptopology.googleapis.com/SchemaR\x04name\"Q\n" +
+	"\x10GetDomainRequest\x12=\n" +
+	"\x04name\x18\x01 \x01(\tB)\xe0A\x02\xfaA#\n" +
+	"!apptopology.googleapis.com/DomainR\x04name\"\x9d\x01\n" +
+	"\x12ListDomainsRequest\x12A\n" +
+	"\x06parent\x18\x01 \x01(\tB)\xe0A\x02\xfaA#\x12!apptopology.googleapis.com/DomainR\x06parent\x12 \n" +
+	"\tpage_size\x18\x02 \x01(\x05B\x03\xe0A\x01R\bpageSize\x12\"\n" +
+	"\n" +
+	"page_token\x18\x03 \x01(\tB\x03\xe0A\x01R\tpageToken\"|\n" +
+	"\x13ListDomainsResponse\x12=\n" +
+	"\adomains\x18\x01 \x03(\v2#.google.cloud.apptopology.v1.DomainR\adomains\x12&\n" +
+	"\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken2\xe6\a\n" +
+	"\vAppTopology\x12\xa3\x02\n" +
+	"#GenerateDiscoveredResourcesTopology\x12G.google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyRequest\x1aH.google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyResponse\"i\xdaA\x15name,topology_domains\x82\xd3\xe4\x93\x02K:\x01*\"F/v1/{name=projects/*/locations/*/discoveredResourcesTopology}:generate\x12\xa2\x01\n" +
+	"\tGetSchema\x12-.google.cloud.apptopology.v1.GetSchemaRequest\x1a#.google.cloud.apptopology.v1.Schema\"A\xdaA\x04name\x82\xd3\xe4\x93\x024\x122/v1/{name=projects/*/locations/*/domains/*/schema}\x12\x9b\x01\n" +
+	"\tGetDomain\x12-.google.cloud.apptopology.v1.GetDomainRequest\x1a#.google.cloud.apptopology.v1.Domain\":\xdaA\x04name\x82\xd3\xe4\x93\x02-\x12+/v1/{name=projects/*/locations/*/domains/*}\x12\xae\x01\n" +
+	"\vListDomains\x12/.google.cloud.apptopology.v1.ListDomainsRequest\x1a0.google.cloud.apptopology.v1.ListDomainsResponse\"<\xdaA\x06parent\x82\xd3\xe4\x93\x02-\x12+/v1/{parent=projects/*/locations/*}/domains\x1a\xbc\x01\xcaA\x1aapptopology.googleapis.com\xd2A\x9b\x01https://www.googleapis.com/auth/apptopology.read-only,https://www.googleapis.com/auth/apptopology.read-write,https://www.googleapis.com/auth/cloud-platformB\x8e\x03\xeaA\xb9\x01\n" +
+	"6apptopology.googleapis.com/DiscoveredResourcesTopology\x12Cprojects/{project}/locations/{location}/discoveredResourcesTopology*\x1ddiscoveredResourcesTopologies2\x1bdiscoveredResourcesTopology\n" +
+	"\x1fcom.google.cloud.apptopology.v1B\fServiceProtoP\x01ZAcloud.google.com/go/apptopology/apiv1/apptopologypb;apptopologypb\xaa\x02\x1bGoogle.Cloud.AppTopology.V1\xca\x02\x1bGoogle\\Cloud\\AppTopology\\V1\xea\x02\x1eGoogle::Cloud::AppTopology::V1b\x06proto3"
+
+var (
+	file_google_cloud_apptopology_v1_service_proto_rawDescOnce sync.Once
+	file_google_cloud_apptopology_v1_service_proto_rawDescData []byte
+)
+
+func file_google_cloud_apptopology_v1_service_proto_rawDescGZIP() []byte {
+	file_google_cloud_apptopology_v1_service_proto_rawDescOnce.Do(func() {
+		file_google_cloud_apptopology_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_service_proto_rawDesc), len(file_google_cloud_apptopology_v1_service_proto_rawDesc)))
+	})
+	return file_google_cloud_apptopology_v1_service_proto_rawDescData
+}
+
+var file_google_cloud_apptopology_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_google_cloud_apptopology_v1_service_proto_goTypes = []any{
+	(*OperationMetadata)(nil),                           // 0: google.cloud.apptopology.v1.OperationMetadata
+	(*GenerateDiscoveredResourcesTopologyRequest)(nil),  // 1: google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyRequest
+	(*GenerateDiscoveredResourcesTopologyResponse)(nil), // 2: google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyResponse
+	(*GetSchemaRequest)(nil),                            // 3: google.cloud.apptopology.v1.GetSchemaRequest
+	(*GetDomainRequest)(nil),                            // 4: google.cloud.apptopology.v1.GetDomainRequest
+	(*ListDomainsRequest)(nil),                          // 5: google.cloud.apptopology.v1.ListDomainsRequest
+	(*ListDomainsResponse)(nil),                         // 6: google.cloud.apptopology.v1.ListDomainsResponse
+	(*timestamppb.Timestamp)(nil),                       // 7: google.protobuf.Timestamp
+	(*GraphPattern)(nil),                                // 8: google.cloud.apptopology.v1.GraphPattern
+	(*Graph)(nil),                                       // 9: google.cloud.apptopology.v1.Graph
+	(*Domain)(nil),                                      // 10: google.cloud.apptopology.v1.Domain
+	(*Schema)(nil),                                      // 11: google.cloud.apptopology.v1.Schema
+}
+var file_google_cloud_apptopology_v1_service_proto_depIdxs = []int32{
+	7,  // 0: google.cloud.apptopology.v1.OperationMetadata.create_time:type_name -> google.protobuf.Timestamp
+	7,  // 1: google.cloud.apptopology.v1.OperationMetadata.end_time:type_name -> google.protobuf.Timestamp
+	8,  // 2: google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyRequest.filter:type_name -> google.cloud.apptopology.v1.GraphPattern
+	9,  // 3: google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyResponse.graph:type_name -> google.cloud.apptopology.v1.Graph
+	10, // 4: google.cloud.apptopology.v1.ListDomainsResponse.domains:type_name -> google.cloud.apptopology.v1.Domain
+	1,  // 5: google.cloud.apptopology.v1.AppTopology.GenerateDiscoveredResourcesTopology:input_type -> google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyRequest
+	3,  // 6: google.cloud.apptopology.v1.AppTopology.GetSchema:input_type -> google.cloud.apptopology.v1.GetSchemaRequest
+	4,  // 7: google.cloud.apptopology.v1.AppTopology.GetDomain:input_type -> google.cloud.apptopology.v1.GetDomainRequest
+	5,  // 8: google.cloud.apptopology.v1.AppTopology.ListDomains:input_type -> google.cloud.apptopology.v1.ListDomainsRequest
+	2,  // 9: google.cloud.apptopology.v1.AppTopology.GenerateDiscoveredResourcesTopology:output_type -> google.cloud.apptopology.v1.GenerateDiscoveredResourcesTopologyResponse
+	11, // 10: google.cloud.apptopology.v1.AppTopology.GetSchema:output_type -> google.cloud.apptopology.v1.Schema
+	10, // 11: google.cloud.apptopology.v1.AppTopology.GetDomain:output_type -> google.cloud.apptopology.v1.Domain
+	6,  // 12: google.cloud.apptopology.v1.AppTopology.ListDomains:output_type -> google.cloud.apptopology.v1.ListDomainsResponse
+	9,  // [9:13] is the sub-list for method output_type
+	5,  // [5:9] is the sub-list for method input_type
+	5,  // [5:5] is the sub-list for extension type_name
+	5,  // [5:5] is the sub-list for extension extendee
+	0,  // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_google_cloud_apptopology_v1_service_proto_init() }
+func file_google_cloud_apptopology_v1_service_proto_init() {
+	if File_google_cloud_apptopology_v1_service_proto != nil {
+		return
+	}
+	file_google_cloud_apptopology_v1_graph_proto_init()
+	file_google_cloud_apptopology_v1_query_proto_init()
+	file_google_cloud_apptopology_v1_schema_proto_init()
+	file_google_cloud_apptopology_v1_service_proto_msgTypes[1].OneofWrappers = []any{
+		(*GenerateDiscoveredResourcesTopologyRequest_Filter)(nil),
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_cloud_apptopology_v1_service_proto_rawDesc), len(file_google_cloud_apptopology_v1_service_proto_rawDesc)),
+			NumEnums:      0,
+			NumMessages:   7,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_google_cloud_apptopology_v1_service_proto_goTypes,
+		DependencyIndexes: file_google_cloud_apptopology_v1_service_proto_depIdxs,
+		MessageInfos:      file_google_cloud_apptopology_v1_service_proto_msgTypes,
+	}.Build()
+	File_google_cloud_apptopology_v1_service_proto = out.File
+	file_google_cloud_apptopology_v1_service_proto_goTypes = nil
+	file_google_cloud_apptopology_v1_service_proto_depIdxs = nil
+}
diff --git a/apptopology/apiv1/apptopologypb/service_grpc.pb.go b/apptopology/apiv1/apptopologypb/service_grpc.pb.go
new file mode 100644
index 0000000..596b33a
--- /dev/null
+++ b/apptopology/apiv1/apptopologypb/service_grpc.pb.go
@@ -0,0 +1,257 @@
+// Copyright 2026 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
+//
+//     http://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-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc             v6.33.2
+// source: google/cloud/apptopology/v1/service.proto
+
+package apptopologypb
+
+import (
+	context "context"
+
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+const (
+	AppTopology_GenerateDiscoveredResourcesTopology_FullMethodName = "/google.cloud.apptopology.v1.AppTopology/GenerateDiscoveredResourcesTopology"
+	AppTopology_GetSchema_FullMethodName                           = "/google.cloud.apptopology.v1.AppTopology/GetSchema"
+	AppTopology_GetDomain_FullMethodName                           = "/google.cloud.apptopology.v1.AppTopology/GetDomain"
+	AppTopology_ListDomains_FullMethodName                         = "/google.cloud.apptopology.v1.AppTopology/ListDomains"
+)
+
+// AppTopologyClient is the client API for AppTopology service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type AppTopologyClient interface {
+	// Generate the topology for all resources in the given project. If the
+	// project represents an
+	// [app
+	// boundary](https://cloud.google.com/app-hub/docs/reference/rest/v1/Boundary),
+	// the topology is generated for all resources in the boundary.
+	GenerateDiscoveredResourcesTopology(ctx context.Context, in *GenerateDiscoveredResourcesTopologyRequest, opts ...grpc.CallOption) (*GenerateDiscoveredResourcesTopologyResponse, error)
+	// Retrieves the schema for the specified topology domain. The schema
+	// defines the NodeTypes and EdgeTypes that are supported in
+	// GenerateDiscoveredResourcesTopology requests and responses for a given
+	// domain.
+	GetSchema(ctx context.Context, in *GetSchemaRequest, opts ...grpc.CallOption) (*Schema, error)
+	// Retrieves the specified topology domain.
+	GetDomain(ctx context.Context, in *GetDomainRequest, opts ...grpc.CallOption) (*Domain, error)
+	// Lists the topology domains available in a specific location.
+	// Only `global` location is supported.
+	ListDomains(ctx context.Context, in *ListDomainsRequest, opts ...grpc.CallOption) (*ListDomainsResponse, error)
+}
+
+type appTopologyClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewAppTopologyClient(cc grpc.ClientConnInterface) AppTopologyClient {
+	return &appTopologyClient{cc}
+}
+
+func (c *appTopologyClient) GenerateDiscoveredResourcesTopology(ctx context.Context, in *GenerateDiscoveredResourcesTopologyRequest, opts ...grpc.CallOption) (*GenerateDiscoveredResourcesTopologyResponse, error) {
+	out := new(GenerateDiscoveredResourcesTopologyResponse)
+	err := c.cc.Invoke(ctx, AppTopology_GenerateDiscoveredResourcesTopology_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *appTopologyClient) GetSchema(ctx context.Context, in *GetSchemaRequest, opts ...grpc.CallOption) (*Schema, error) {
+	out := new(Schema)
+	err := c.cc.Invoke(ctx, AppTopology_GetSchema_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *appTopologyClient) GetDomain(ctx context.Context, in *GetDomainRequest, opts ...grpc.CallOption) (*Domain, error) {
+	out := new(Domain)
+	err := c.cc.Invoke(ctx, AppTopology_GetDomain_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *appTopologyClient) ListDomains(ctx context.Context, in *ListDomainsRequest, opts ...grpc.CallOption) (*ListDomainsResponse, error) {
+	out := new(ListDomainsResponse)
+	err := c.cc.Invoke(ctx, AppTopology_ListDomains_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// AppTopologyServer is the server API for AppTopology service.
+// All implementations should embed UnimplementedAppTopologyServer
+// for forward compatibility
+type AppTopologyServer interface {
+	// Generate the topology for all resources in the given project. If the
+	// project represents an
+	// [app
+	// boundary](https://cloud.google.com/app-hub/docs/reference/rest/v1/Boundary),
+	// the topology is generated for all resources in the boundary.
+	GenerateDiscoveredResourcesTopology(context.Context, *GenerateDiscoveredResourcesTopologyRequest) (*GenerateDiscoveredResourcesTopologyResponse, error)
+	// Retrieves the schema for the specified topology domain. The schema
+	// defines the NodeTypes and EdgeTypes that are supported in
+	// GenerateDiscoveredResourcesTopology requests and responses for a given
+	// domain.
+	GetSchema(context.Context, *GetSchemaRequest) (*Schema, error)
+	// Retrieves the specified topology domain.
+	GetDomain(context.Context, *GetDomainRequest) (*Domain, error)
+	// Lists the topology domains available in a specific location.
+	// Only `global` location is supported.
+	ListDomains(context.Context, *ListDomainsRequest) (*ListDomainsResponse, error)
+}
+
+// UnimplementedAppTopologyServer should be embedded to have forward compatible implementations.
+type UnimplementedAppTopologyServer struct {
+}
+
+func (UnimplementedAppTopologyServer) GenerateDiscoveredResourcesTopology(context.Context, *GenerateDiscoveredResourcesTopologyRequest) (*GenerateDiscoveredResourcesTopologyResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GenerateDiscoveredResourcesTopology not implemented")
+}
+func (UnimplementedAppTopologyServer) GetSchema(context.Context, *GetSchemaRequest) (*Schema, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetSchema not implemented")
+}
+func (UnimplementedAppTopologyServer) GetDomain(context.Context, *GetDomainRequest) (*Domain, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetDomain not implemented")
+}
+func (UnimplementedAppTopologyServer) ListDomains(context.Context, *ListDomainsRequest) (*ListDomainsResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListDomains not implemented")
+}
+
+// UnsafeAppTopologyServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to AppTopologyServer will
+// result in compilation errors.
+type UnsafeAppTopologyServer interface {
+	mustEmbedUnimplementedAppTopologyServer()
+}
+
+func RegisterAppTopologyServer(s grpc.ServiceRegistrar, srv AppTopologyServer) {
+	s.RegisterService(&AppTopology_ServiceDesc, srv)
+}
+
+func _AppTopology_GenerateDiscoveredResourcesTopology_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GenerateDiscoveredResourcesTopologyRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AppTopologyServer).GenerateDiscoveredResourcesTopology(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: AppTopology_GenerateDiscoveredResourcesTopology_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AppTopologyServer).GenerateDiscoveredResourcesTopology(ctx, req.(*GenerateDiscoveredResourcesTopologyRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AppTopology_GetSchema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetSchemaRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AppTopologyServer).GetSchema(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: AppTopology_GetSchema_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AppTopologyServer).GetSchema(ctx, req.(*GetSchemaRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AppTopology_GetDomain_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetDomainRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AppTopologyServer).GetDomain(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: AppTopology_GetDomain_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AppTopologyServer).GetDomain(ctx, req.(*GetDomainRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _AppTopology_ListDomains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListDomainsRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AppTopologyServer).ListDomains(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: AppTopology_ListDomains_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AppTopologyServer).ListDomains(ctx, req.(*ListDomainsRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// AppTopology_ServiceDesc is the grpc.ServiceDesc for AppTopology service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var AppTopology_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "google.cloud.apptopology.v1.AppTopology",
+	HandlerType: (*AppTopologyServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GenerateDiscoveredResourcesTopology",
+			Handler:    _AppTopology_GenerateDiscoveredResourcesTopology_Handler,
+		},
+		{
+			MethodName: "GetSchema",
+			Handler:    _AppTopology_GetSchema_Handler,
+		},
+		{
+			MethodName: "GetDomain",
+			Handler:    _AppTopology_GetDomain_Handler,
+		},
+		{
+			MethodName: "ListDomains",
+			Handler:    _AppTopology_ListDomains_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "google/cloud/apptopology/v1/service.proto",
+}
diff --git a/apptopology/apiv1/auxiliary.go b/apptopology/apiv1/auxiliary.go
new file mode 100644
index 0000000..dbff4af
--- /dev/null
+++ b/apptopology/apiv1/auxiliary.go
@@ -0,0 +1,186 @@
+// Copyright 2026 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 apptopology
+
+import (
+	"iter"
+
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+	gaxiter "github.com/googleapis/gax-go/v2/iterator"
+	"google.golang.org/api/iterator"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+)
+
+// All returns an iterator. If an error is returned by the iterator, the
+// iterator will stop after that iteration.
+func (it *DomainIterator) All() iter.Seq2[*apptopologypb.Domain, error] {
+	return gaxiter.RangeAdapter(it.Next)
+}
+
+// DomainIterator manages a stream of *apptopologypb.Domain.
+type DomainIterator struct {
+	items    []*apptopologypb.Domain
+	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 []*apptopologypb.Domain, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the [google.golang.org/api/iterator] package for details.
+func (it *DomainIterator) 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 *DomainIterator) Next() (*apptopologypb.Domain, error) {
+	var item *apptopologypb.Domain
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *DomainIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *DomainIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
+
+// All returns an iterator. If an error is returned by the iterator, the
+// iterator will stop after that iteration.
+func (it *LocationIterator) All() iter.Seq2[*locationpb.Location, error] {
+	return gaxiter.RangeAdapter(it.Next)
+}
+
+// LocationIterator manages a stream of *locationpb.Location.
+type LocationIterator struct {
+	items    []*locationpb.Location
+	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 []*locationpb.Location, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the [google.golang.org/api/iterator] package for details.
+func (it *LocationIterator) 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 *LocationIterator) Next() (*locationpb.Location, error) {
+	var item *locationpb.Location
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *LocationIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *LocationIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
+
+// All returns an iterator. If an error is returned by the iterator, the
+// iterator will stop after that iteration.
+func (it *OperationIterator) All() iter.Seq2[*longrunningpb.Operation, error] {
+	return gaxiter.RangeAdapter(it.Next)
+}
+
+// OperationIterator manages a stream of *longrunningpb.Operation.
+type OperationIterator struct {
+	items    []*longrunningpb.Operation
+	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 []*longrunningpb.Operation, nextPageToken string, err error)
+}
+
+// PageInfo supports pagination. See the [google.golang.org/api/iterator] package for details.
+func (it *OperationIterator) 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 *OperationIterator) Next() (*longrunningpb.Operation, error) {
+	var item *longrunningpb.Operation
+	if err := it.nextFunc(); err != nil {
+		return item, err
+	}
+	item = it.items[0]
+	it.items = it.items[1:]
+	return item, nil
+}
+
+func (it *OperationIterator) bufLen() int {
+	return len(it.items)
+}
+
+func (it *OperationIterator) takeBuf() interface{} {
+	b := it.items
+	it.items = nil
+	return b
+}
diff --git a/apptopology/apiv1/doc.go b/apptopology/apiv1/doc.go
new file mode 100644
index 0000000..b4292d4
--- /dev/null
+++ b/apptopology/apiv1/doc.go
@@ -0,0 +1,83 @@
+// Copyright 2026 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 apptopology is an auto-generated package for the
+// App Topology API.
+//
+//	NOTE: This package is in beta. It is not stable, and may be subject to changes.
+//
+// # General documentation
+//
+// For information that is relevant for all client libraries please reference
+// https://pkg.go.dev/cloud.google.com/go#pkg-overview. Some information on this
+// page includes:
+//
+//   - [Authentication and Authorization]
+//   - [Timeouts and Cancellation]
+//   - [Testing against Client Libraries]
+//   - [Debugging Client Libraries]
+//   - [Inspecting errors]
+//
+// # Example usage
+//
+// To get started with this package, create a client.
+//
+//	// go get cloud.google.com/go/apptopology/apiv1@latest
+//	ctx := context.Background()
+//	// This snippet has been automatically generated and should be regarded as a code template only.
+//	// It will require modifications to work:
+//	// - It may require correct/in-range values for request initialization.
+//	// - It may require specifying regional endpoints when creating the service client as shown in:
+//	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+//	c, err := apptopology.NewClient(ctx)
+//	if err != nil {
+//		// TODO: Handle error.
+//	}
+//	defer c.Close()
+//
+// The client will use your default application credentials. Clients should be reused instead of created as needed.
+// The methods of Client are safe for concurrent use by multiple goroutines.
+// The returned client must be Closed when it is done being used.
+//
+// # Using the Client
+//
+// The following is an example of making an API call with the newly created client, mentioned above.
+//
+//	req := &apptopologypb.GenerateDiscoveredResourcesTopologyRequest{
+//		// TODO: Fill request struct fields.
+//		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GenerateDiscoveredResourcesTopologyRequest.
+//	}
+//	resp, err := c.GenerateDiscoveredResourcesTopology(ctx, req)
+//	if err != nil {
+//		// TODO: Handle error.
+//	}
+//	// TODO: Use resp.
+//	_ = resp
+//
+// # 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.
+//
+// [Authentication and Authorization]: https://pkg.go.dev/cloud.google.com/go#hdr-Authentication_and_Authorization
+// [Timeouts and Cancellation]: https://pkg.go.dev/cloud.google.com/go#hdr-Timeouts_and_Cancellation
+// [Testing against Client Libraries]: https://pkg.go.dev/cloud.google.com/go#hdr-Testing
+// [Debugging Client Libraries]: https://pkg.go.dev/cloud.google.com/go#hdr-Debugging
+// [Inspecting errors]: https://pkg.go.dev/cloud.google.com/go#hdr-Inspecting_errors
+package apptopology // import "cloud.google.com/go/apptopology/apiv1"
diff --git a/apptopology/apiv1/gapic_metadata.json b/apptopology/apiv1/gapic_metadata.json
new file mode 100644
index 0000000..d2d83e0
--- /dev/null
+++ b/apptopology/apiv1/gapic_metadata.json
@@ -0,0 +1,123 @@
+{
+  "schema": "1.0",
+  "comment": "This file maps proto services/RPCs to the corresponding library clients/methods.",
+  "language": "go",
+  "protoPackage": "google.cloud.apptopology.v1",
+  "libraryPackage": "cloud.google.com/go/apptopology/apiv1",
+  "services": {
+    "AppTopology": {
+      "clients": {
+        "grpc": {
+          "libraryClient": "Client",
+          "rpcs": {
+            "CancelOperation": {
+              "methods": [
+                "CancelOperation"
+              ]
+            },
+            "DeleteOperation": {
+              "methods": [
+                "DeleteOperation"
+              ]
+            },
+            "GenerateDiscoveredResourcesTopology": {
+              "methods": [
+                "GenerateDiscoveredResourcesTopology"
+              ]
+            },
+            "GetDomain": {
+              "methods": [
+                "GetDomain"
+              ]
+            },
+            "GetLocation": {
+              "methods": [
+                "GetLocation"
+              ]
+            },
+            "GetOperation": {
+              "methods": [
+                "GetOperation"
+              ]
+            },
+            "GetSchema": {
+              "methods": [
+                "GetSchema"
+              ]
+            },
+            "ListDomains": {
+              "methods": [
+                "ListDomains"
+              ]
+            },
+            "ListLocations": {
+              "methods": [
+                "ListLocations"
+              ]
+            },
+            "ListOperations": {
+              "methods": [
+                "ListOperations"
+              ]
+            }
+          }
+        },
+        "rest": {
+          "libraryClient": "Client",
+          "rpcs": {
+            "CancelOperation": {
+              "methods": [
+                "CancelOperation"
+              ]
+            },
+            "DeleteOperation": {
+              "methods": [
+                "DeleteOperation"
+              ]
+            },
+            "GenerateDiscoveredResourcesTopology": {
+              "methods": [
+                "GenerateDiscoveredResourcesTopology"
+              ]
+            },
+            "GetDomain": {
+              "methods": [
+                "GetDomain"
+              ]
+            },
+            "GetLocation": {
+              "methods": [
+                "GetLocation"
+              ]
+            },
+            "GetOperation": {
+              "methods": [
+                "GetOperation"
+              ]
+            },
+            "GetSchema": {
+              "methods": [
+                "GetSchema"
+              ]
+            },
+            "ListDomains": {
+              "methods": [
+                "ListDomains"
+              ]
+            },
+            "ListLocations": {
+              "methods": [
+                "ListLocations"
+              ]
+            },
+            "ListOperations": {
+              "methods": [
+                "ListOperations"
+              ]
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/apptopology/apiv1/helpers.go b/apptopology/apiv1/helpers.go
new file mode 100644
index 0000000..5527896
--- /dev/null
+++ b/apptopology/apiv1/helpers.go
@@ -0,0 +1,107 @@
+// Copyright 2026 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 apptopology
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"log/slog"
+	"net/http"
+
+	"github.com/googleapis/gax-go/v2/internallog"
+	"github.com/googleapis/gax-go/v2/internallog/grpclog"
+	"google.golang.org/api/googleapi"
+	"google.golang.org/api/option"
+	"google.golang.org/grpc"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const serviceName = "apptopology.googleapis.com"
+
+var protoVersion = fmt.Sprintf("1.%d", protoimpl.MaxVersion)
+
+// 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)
+
+var versionClient string
+
+func getVersionClient() string {
+	if versionClient == "" {
+		return "UNKNOWN"
+	}
+	return versionClient
+}
+
+// DefaultAuthScopes reports the default set of authentication scopes to use with this package.
+func DefaultAuthScopes() []string {
+	return []string{
+		"https://www.googleapis.com/auth/apptopology.read-only",
+		"https://www.googleapis.com/auth/apptopology.read-write",
+		"https://www.googleapis.com/auth/cloud-platform",
+	}
+}
+
+func executeHTTPRequestWithResponse(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, *http.Response, error) {
+	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, nil, err
+	}
+	defer resp.Body.Close()
+	buf, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return nil, nil, err
+	}
+	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, buf))
+	if err = googleapi.CheckResponseWithBody(resp, buf); err != nil {
+		return nil, nil, err
+	}
+	return buf, resp, nil
+}
+
+func executeHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) ([]byte, error) {
+	buf, _, err := executeHTTPRequestWithResponse(ctx, client, req, logger, body, rpc)
+	return buf, err
+}
+
+func executeStreamingHTTPRequest(ctx context.Context, client *http.Client, req *http.Request, logger *slog.Logger, body []byte, rpc string) (*http.Response, error) {
+	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", internallog.HTTPRequest(req, body))
+	resp, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", internallog.HTTPResponse(resp, nil))
+	if err = googleapi.CheckResponse(resp); err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+func executeRPC[I proto.Message, O proto.Message](ctx context.Context, fn func(context.Context, I, ...grpc.CallOption) (O, error), req I, opts []grpc.CallOption, logger *slog.Logger, rpc string) (O, error) {
+	var zero O
+	logger.DebugContext(ctx, "api request", "serviceName", serviceName, "rpcName", rpc, "request", grpclog.ProtoMessageRequest(ctx, req))
+	resp, err := fn(ctx, req, opts...)
+	if err != nil {
+		return zero, err
+	}
+	logger.DebugContext(ctx, "api response", "serviceName", serviceName, "rpcName", rpc, "response", grpclog.ProtoMessageResponse(resp))
+	return resp, err
+}
diff --git a/apptopology/apiv1/version.go b/apptopology/apiv1/version.go
new file mode 100644
index 0000000..ebb347d
--- /dev/null
+++ b/apptopology/apiv1/version.go
@@ -0,0 +1,23 @@
+// Copyright 2026 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 gapicgen. DO NOT EDIT.
+
+package apptopology
+
+import "cloud.google.com/go/apptopology/internal"
+
+func init() {
+	versionClient = internal.Version
+}
diff --git a/apptopology/examples/apiv1/Client/CancelOperation/main.go b/apptopology/examples/apiv1/Client/CancelOperation/main.go
new file mode 100644
index 0000000..e763580
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/CancelOperation/main.go
@@ -0,0 +1,53 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_CancelOperation_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.CancelOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#CancelOperationRequest.
+	}
+	err = c.CancelOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+// [END apptopology_v1_generated_AppTopology_CancelOperation_sync]
diff --git a/apptopology/examples/apiv1/Client/DeleteOperation/main.go b/apptopology/examples/apiv1/Client/DeleteOperation/main.go
new file mode 100644
index 0000000..5e88b4c
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/DeleteOperation/main.go
@@ -0,0 +1,53 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_DeleteOperation_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.DeleteOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#DeleteOperationRequest.
+	}
+	err = c.DeleteOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+}
+
+// [END apptopology_v1_generated_AppTopology_DeleteOperation_sync]
diff --git a/apptopology/examples/apiv1/Client/GenerateDiscoveredResourcesTopology/main.go b/apptopology/examples/apiv1/Client/GenerateDiscoveredResourcesTopology/main.go
new file mode 100644
index 0000000..8e2d723
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/GenerateDiscoveredResourcesTopology/main.go
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_GenerateDiscoveredResourcesTopology_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GenerateDiscoveredResourcesTopologyRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GenerateDiscoveredResourcesTopologyRequest.
+	}
+	resp, err := c.GenerateDiscoveredResourcesTopology(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+// [END apptopology_v1_generated_AppTopology_GenerateDiscoveredResourcesTopology_sync]
diff --git a/apptopology/examples/apiv1/Client/GetDomain/main.go b/apptopology/examples/apiv1/Client/GetDomain/main.go
new file mode 100644
index 0000000..5cef58e
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/GetDomain/main.go
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_GetDomain_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GetDomainRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GetDomainRequest.
+	}
+	resp, err := c.GetDomain(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+// [END apptopology_v1_generated_AppTopology_GetDomain_sync]
diff --git a/apptopology/examples/apiv1/Client/GetLocation/main.go b/apptopology/examples/apiv1/Client/GetLocation/main.go
new file mode 100644
index 0000000..49ed570
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/GetLocation/main.go
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_GetLocation_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &locationpb.GetLocationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/location#GetLocationRequest.
+	}
+	resp, err := c.GetLocation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+// [END apptopology_v1_generated_AppTopology_GetLocation_sync]
diff --git a/apptopology/examples/apiv1/Client/GetOperation/main.go b/apptopology/examples/apiv1/Client/GetOperation/main.go
new file mode 100644
index 0000000..d91e170
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/GetOperation/main.go
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_GetOperation_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.GetOperationRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#GetOperationRequest.
+	}
+	resp, err := c.GetOperation(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+// [END apptopology_v1_generated_AppTopology_GetOperation_sync]
diff --git a/apptopology/examples/apiv1/Client/GetSchema/main.go b/apptopology/examples/apiv1/Client/GetSchema/main.go
new file mode 100644
index 0000000..18a990d
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/GetSchema/main.go
@@ -0,0 +1,55 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_GetSchema_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.GetSchemaRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#GetSchemaRequest.
+	}
+	resp, err := c.GetSchema(ctx, req)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	// TODO: Use resp.
+	_ = resp
+}
+
+// [END apptopology_v1_generated_AppTopology_GetSchema_sync]
diff --git a/apptopology/examples/apiv1/Client/ListDomains/main.go b/apptopology/examples/apiv1/Client/ListDomains/main.go
new file mode 100644
index 0000000..e52192d
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/ListDomains/main.go
@@ -0,0 +1,68 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_ListDomains_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	apptopologypb "cloud.google.com/go/apptopology/apiv1/apptopologypb"
+	"google.golang.org/api/iterator"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &apptopologypb.ListDomainsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/apptopology/apiv1/apptopologypb#ListDomainsRequest.
+	}
+	it := c.ListDomains(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*apptopologypb.ListDomainsResponse)
+	}
+}
+
+// [END apptopology_v1_generated_AppTopology_ListDomains_sync]
diff --git a/apptopology/examples/apiv1/Client/ListLocations/main.go b/apptopology/examples/apiv1/Client/ListLocations/main.go
new file mode 100644
index 0000000..f66455a
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/ListLocations/main.go
@@ -0,0 +1,68 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_ListLocations_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	"google.golang.org/api/iterator"
+	locationpb "google.golang.org/genproto/googleapis/cloud/location"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &locationpb.ListLocationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/location#ListLocationsRequest.
+	}
+	it := c.ListLocations(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*locationpb.ListLocationsResponse)
+	}
+}
+
+// [END apptopology_v1_generated_AppTopology_ListLocations_sync]
diff --git a/apptopology/examples/apiv1/Client/ListOperations/main.go b/apptopology/examples/apiv1/Client/ListOperations/main.go
new file mode 100644
index 0000000..3c6267f
--- /dev/null
+++ b/apptopology/examples/apiv1/Client/ListOperations/main.go
@@ -0,0 +1,68 @@
+// Copyright 2026 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.
+
+// [START apptopology_v1_generated_AppTopology_ListOperations_sync]
+
+//go:build examples
+
+package main
+
+import (
+	"context"
+
+	apptopology "cloud.google.com/go/apptopology/apiv1"
+	longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
+	"google.golang.org/api/iterator"
+)
+
+func main() {
+	ctx := context.Background()
+	// This snippet has been automatically generated and should be regarded as a code template only.
+	// It will require modifications to work:
+	// - It may require correct/in-range values for request initialization.
+	// - It may require specifying regional endpoints when creating the service client as shown in:
+	//   https://pkg.go.dev/cloud.google.com/go#hdr-Client_Options
+	c, err := apptopology.NewClient(ctx)
+	if err != nil {
+		// TODO: Handle error.
+	}
+	defer c.Close()
+
+	req := &longrunningpb.ListOperationsRequest{
+		// TODO: Fill request struct fields.
+		// See https://pkg.go.dev/cloud.google.com/go/longrunning/autogen/longrunningpb#ListOperationsRequest.
+	}
+	it := c.ListOperations(ctx, req)
+	for {
+		resp, err := it.Next()
+		if err == iterator.Done {
+			break
+		}
+		if err != nil {
+			// TODO: Handle error.
+		}
+		// TODO: Use resp.
+		_ = resp
+
+		// If you need to access the underlying RPC response,
+		// you can do so by casting the `Response` as below.
+		// Otherwise, remove this line. Only populated after
+		// first call to Next(). Not safe for concurrent access.
+		_ = it.Response.(*longrunningpb.ListOperationsResponse)
+	}
+}
+
+// [END apptopology_v1_generated_AppTopology_ListOperations_sync]
diff --git a/apptopology/examples/apiv1/snippet_metadata.google.cloud.apptopology.v1.json b/apptopology/examples/apiv1/snippet_metadata.google.cloud.apptopology.v1.json
new file mode 100644
index 0000000..67cd402
--- /dev/null
+++ b/apptopology/examples/apiv1/snippet_metadata.google.cloud.apptopology.v1.json
@@ -0,0 +1,473 @@
+{
+  "clientLibrary": {
+    "apis": [
+      {
+        "id": "google.cloud.apptopology.v1",
+        "version": "v1"
+      }
+    ],
+    "language": "GO",
+    "name": "cloud.google.com/go/apptopology/apiv1",
+    "version": "0.0.0"
+  },
+  "snippets": [
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.CancelOperation",
+        "method": {
+          "fullName": "google.longrunning.Operations.CancelOperation",
+          "service": {
+            "fullName": "google.longrunning.Operations",
+            "shortName": "Operations"
+          },
+          "shortName": "CancelOperation"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "longrunningpb.CancelOperationRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "shortName": "CancelOperation"
+      },
+      "description": "CancelOperation is a utility method from google.longrunning.Operations.",
+      "file": "Client/CancelOperation/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_CancelOperation_sync",
+      "segments": [
+        {
+          "end": 53,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology CancelOperation Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.DeleteOperation",
+        "method": {
+          "fullName": "google.longrunning.Operations.DeleteOperation",
+          "service": {
+            "fullName": "google.longrunning.Operations",
+            "shortName": "Operations"
+          },
+          "shortName": "DeleteOperation"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "longrunningpb.DeleteOperationRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "shortName": "DeleteOperation"
+      },
+      "description": "DeleteOperation is a utility method from google.longrunning.Operations.",
+      "file": "Client/DeleteOperation/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_DeleteOperation_sync",
+      "segments": [
+        {
+          "end": 53,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology DeleteOperation Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.GenerateDiscoveredResourcesTopology",
+        "method": {
+          "fullName": "google.cloud.apptopology.v1.AppTopology.GenerateDiscoveredResourcesTopology",
+          "service": {
+            "fullName": "google.cloud.apptopology.v1.AppTopology",
+            "shortName": "AppTopology"
+          },
+          "shortName": "GenerateDiscoveredResourcesTopology"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "apptopologypb.GenerateDiscoveredResourcesTopologyRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "*apptopologypb.GenerateDiscoveredResourcesTopologyResponse",
+        "shortName": "GenerateDiscoveredResourcesTopology"
+      },
+      "description": "GenerateDiscoveredResourcesTopology generate the topology for all resources in the given project. If the\nproject represents an\n[app\nboundary](https: //cloud.google.com/app-hub/docs/reference/rest/v1/Boundary),\nthe topology is generated for all resources in the boundary.",
+      "file": "Client/GenerateDiscoveredResourcesTopology/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_GenerateDiscoveredResourcesTopology_sync",
+      "segments": [
+        {
+          "end": 55,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology GenerateDiscoveredResourcesTopology Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.GetDomain",
+        "method": {
+          "fullName": "google.cloud.apptopology.v1.AppTopology.GetDomain",
+          "service": {
+            "fullName": "google.cloud.apptopology.v1.AppTopology",
+            "shortName": "AppTopology"
+          },
+          "shortName": "GetDomain"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "apptopologypb.GetDomainRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "*apptopologypb.Domain",
+        "shortName": "GetDomain"
+      },
+      "description": "GetDomain retrieves the specified topology domain.",
+      "file": "Client/GetDomain/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_GetDomain_sync",
+      "segments": [
+        {
+          "end": 55,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology GetDomain Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.GetLocation",
+        "method": {
+          "fullName": "google.cloud.location.Locations.GetLocation",
+          "service": {
+            "fullName": "google.cloud.location.Locations",
+            "shortName": "Locations"
+          },
+          "shortName": "GetLocation"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "locationpb.GetLocationRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "*locationpb.Location",
+        "shortName": "GetLocation"
+      },
+      "description": "GetLocation gets information about a location.",
+      "file": "Client/GetLocation/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_GetLocation_sync",
+      "segments": [
+        {
+          "end": 55,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology GetLocation Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.GetOperation",
+        "method": {
+          "fullName": "google.longrunning.Operations.GetOperation",
+          "service": {
+            "fullName": "google.longrunning.Operations",
+            "shortName": "Operations"
+          },
+          "shortName": "GetOperation"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "longrunningpb.GetOperationRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "*longrunningpb.Operation",
+        "shortName": "GetOperation"
+      },
+      "description": "GetOperation is a utility method from google.longrunning.Operations.",
+      "file": "Client/GetOperation/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_GetOperation_sync",
+      "segments": [
+        {
+          "end": 55,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology GetOperation Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.GetSchema",
+        "method": {
+          "fullName": "google.cloud.apptopology.v1.AppTopology.GetSchema",
+          "service": {
+            "fullName": "google.cloud.apptopology.v1.AppTopology",
+            "shortName": "AppTopology"
+          },
+          "shortName": "GetSchema"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "apptopologypb.GetSchemaRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "*apptopologypb.Schema",
+        "shortName": "GetSchema"
+      },
+      "description": "GetSchema retrieves the schema for the specified topology domain. The schema\ndefines the NodeTypes and EdgeTypes that are supported in\nGenerateDiscoveredResourcesTopology requests and responses for a given\ndomain.",
+      "file": "Client/GetSchema/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_GetSchema_sync",
+      "segments": [
+        {
+          "end": 55,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology GetSchema Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.ListDomains",
+        "method": {
+          "fullName": "google.cloud.apptopology.v1.AppTopology.ListDomains",
+          "service": {
+            "fullName": "google.cloud.apptopology.v1.AppTopology",
+            "shortName": "AppTopology"
+          },
+          "shortName": "ListDomains"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "apptopologypb.ListDomainsRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "DomainIterator",
+        "shortName": "ListDomains"
+      },
+      "description": "ListDomains lists the topology domains available in a specific location.\nOnly `global` location is supported.",
+      "file": "Client/ListDomains/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_ListDomains_sync",
+      "segments": [
+        {
+          "end": 68,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology ListDomains Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.ListLocations",
+        "method": {
+          "fullName": "google.cloud.location.Locations.ListLocations",
+          "service": {
+            "fullName": "google.cloud.location.Locations",
+            "shortName": "Locations"
+          },
+          "shortName": "ListLocations"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "locationpb.ListLocationsRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "LocationIterator",
+        "shortName": "ListLocations"
+      },
+      "description": "ListLocations lists information about the supported locations for this service.\n\nThis method lists locations based on the resource scope provided in\nthe [ListLocationsRequest.name][google.cloud.location.ListLocationsRequest.name] field: *\n**Global locations**: If `name` is empty, the method lists the\npublic locations available to all projects. * **Project-specific\nlocations**: If `name` follows the format\n`projects/{project}`, the method lists locations visible to that\nspecific project. This includes public, private, or other\nproject-specific locations enabled for the project.\n\nFor gRPC and client library implementations, the resource name is\npassed as the `name` field. For direct service calls, the resource\nname is\nincorporated into the request path based on the specific service\nimplementation and version.",
+      "file": "Client/ListLocations/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_ListLocations_sync",
+      "segments": [
+        {
+          "end": 68,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology ListLocations Sample"
+    },
+    {
+      "clientMethod": {
+        "client": {
+          "fullName": "google.cloud.apptopology.v1.Client",
+          "shortName": "Client"
+        },
+        "fullName": "google.cloud.apptopology.v1.Client.ListOperations",
+        "method": {
+          "fullName": "google.longrunning.Operations.ListOperations",
+          "service": {
+            "fullName": "google.longrunning.Operations",
+            "shortName": "Operations"
+          },
+          "shortName": "ListOperations"
+        },
+        "parameters": [
+          {
+            "name": "ctx",
+            "type": "context.Context"
+          },
+          {
+            "name": "req",
+            "type": "longrunningpb.ListOperationsRequest"
+          },
+          {
+            "name": "opts",
+            "type": "...gax.CallOption"
+          }
+        ],
+        "resultType": "OperationIterator",
+        "shortName": "ListOperations"
+      },
+      "description": "ListOperations is a utility method from google.longrunning.Operations.",
+      "file": "Client/ListOperations/main.go",
+      "language": "GO",
+      "origin": "API_DEFINITION",
+      "regionTag": "apptopology_v1_generated_AppTopology_ListOperations_sync",
+      "segments": [
+        {
+          "end": 68,
+          "start": 18,
+          "type": "FULL"
+        }
+      ],
+      "title": "apptopology ListOperations Sample"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/apptopology/go.mod b/apptopology/go.mod
new file mode 100644
index 0000000..cb1f2d8
--- /dev/null
+++ b/apptopology/go.mod
@@ -0,0 +1,39 @@
+module cloud.google.com/go/apptopology
+
+go 1.25.0
+
+require (
+	cloud.google.com/go/longrunning v1.2.0
+	github.com/googleapis/gax-go/v2 v2.24.0
+	google.golang.org/api v0.294.0
+	google.golang.org/genproto v0.0.0-20260825221802-da73d73af1c5
+	google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5
+	google.golang.org/grpc v1.83.2
+	google.golang.org/protobuf v1.36.12
+)
+
+require (
+	cloud.google.com/go/auth v0.23.2 // indirect
+	cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
+	cloud.google.com/go/compute/metadata v0.9.0 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
+	github.com/felixge/httpsnoop v1.0.4 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/google/s2a-go v0.1.9 // indirect
+	github.com/googleapis/enterprise-certificate-proxy v0.3.20 // indirect
+	go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 // indirect
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
+	go.opentelemetry.io/otel v1.44.0 // indirect
+	go.opentelemetry.io/otel/metric v1.44.0 // indirect
+	go.opentelemetry.io/otel/trace v1.44.0 // indirect
+	golang.org/x/crypto v0.55.0 // indirect
+	golang.org/x/net v0.58.0 // indirect
+	golang.org/x/oauth2 v0.36.0 // indirect
+	golang.org/x/sync v0.22.0 // indirect
+	golang.org/x/sys v0.47.0 // indirect
+	golang.org/x/text v0.41.0 // indirect
+	golang.org/x/time v0.15.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect
+)
diff --git a/apptopology/go.sum b/apptopology/go.sum
new file mode 100644
index 0000000..234998c
--- /dev/null
+++ b/apptopology/go.sum
@@ -0,0 +1,90 @@
+cloud.google.com/go/auth v0.23.2 h1:pxSCpfiji41hpzpPdMCftEUCezpgpqmmDdYiAjCKXxo=
+cloud.google.com/go/auth v0.23.2/go.mod h1:4DhBRcqvtljQN3dJ57qtqbib5ZGCYE5f2crfiiC2EM0=
+cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
+cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
+cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
+cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
+cloud.google.com/go/longrunning v1.2.0 h1:WjYH3YHBGCxGJP9M4dWGHBfXr/cFIjMkNgWcJj7/iMM=
+cloud.google.com/go/longrunning v1.2.0/go.mod h1:5KMQALFGOCtFoi2xSOA1u3H7WKlhmckgiyFw7+LGQp0=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=
+github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
+github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ=
+github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A=
+github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
+github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
+github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/enterprise-certificate-proxy v0.3.20 h1:t/xL64VUoN69MuMRQuJETqYGOw4Z9mSRJK9epIEtwFk=
+github.com/googleapis/enterprise-certificate-proxy v0.3.20/go.mod h1:L3D/IQExI6LqEjBdXcZQ1WluSgigQmSwBboFstVPM4w=
+github.com/googleapis/gax-go/v2 v2.24.0 h1:myMaPYyF9MecEmvQqMqomIwn9t/4KCZN9qnwsS76wlg=
+github.com/googleapis/gax-go/v2 v2.24.0/go.mod h1:IaTHBDd7NHxSCiu0vEs8pQZu4dGZrWwuSoxCnk16OFM=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
+github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0/go.mod h1:NoUCKYWK+3ecatC4HjkRktREheMeEtrXoQxrqYFeHSc=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
+go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
+go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
+go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
+go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
+go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
+go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
+go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
+go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
+go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
+go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
+golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
+golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
+golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
+golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
+golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
+golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
+golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
+golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/api v0.294.0 h1:8gASjJxdtcIieB3OqbkLcF0FfbXVNqKtU5iozD1ssvA=
+google.golang.org/api v0.294.0/go.mod h1:02qB8+Ox1ZFzcaKFMguy1nQLJmSIyvV6Ff4txJEXtl4=
+google.golang.org/genproto v0.0.0-20260825221802-da73d73af1c5 h1:jPP56YzdY899KJ5W7efXHt/CkjlVfAaoFOwdi/IEAFA=
+google.golang.org/genproto v0.0.0-20260825221802-da73d73af1c5/go.mod h1:gutZdP0DwAHp4vu5WaXgEK7tjsJ77ZEqzlOFWGZGziE=
+google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5 h1:izFU9hz7aeLI/Mi1J0991ae+xcwRLr7hTqWnB/9aIIU=
+google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5/go.mod h1:3LhxRw4YYkf+ylAfgaY9JlVLFKhokkCV8duhLLe7+t0=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA=
+google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
+google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
+google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
+google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/apptopology/internal/version.go b/apptopology/internal/version.go
new file mode 100644
index 0000000..2e4d6f5
--- /dev/null
+++ b/apptopology/internal/version.go
@@ -0,0 +1,20 @@
+// Copyright 2026 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 gapicgen. DO NOT EDIT.
+
+package internal
+
+// Version is the current tagged release of the library.
+const Version = "0.0.0"
diff --git a/librarian.yaml b/librarian.yaml
index c2cd896..bf658d4 100644
--- a/librarian.yaml
+++ b/librarian.yaml
@@ -151,6 +151,11 @@
       - path: google/apps/events/subscriptions/v1
       - path: google/apps/meet/v2beta
       - path: google/apps/events/subscriptions/v1beta
+  - name: apptopology
+    version: 0.0.0
+    apis:
+      - path: google/cloud/apptopology/v1
+    copyright_year: "2026"
   - name: area120
     version: 0.15.0
     apis:
diff --git a/release-please-bulk-config.json b/release-please-bulk-config.json
index c6841c5..9a2a8e6 100644
--- a/release-please-bulk-config.json
+++ b/release-please-bulk-config.json
@@ -234,6 +234,16 @@
         }
       ]
     },
+    "apptopology": {
+      "component": "apptopology",
+      "extra-files": [
+        {
+          "jsonpath": "$.clientLibrary.version",
+          "path": "examples/apiv1/snippet_metadata.google.cloud.apptopology.v1.json",
+          "type": "json"
+        }
+      ]
+    },
     "area120": {
       "component": "area120",
       "extra-files": [